Low udp performance with local instances

Hello my dear community!
I have weird performance drops with udp - huge packet loss.
Simple receiver and sender:

####################################################################
#coding: utf-8

require “socket”

httpd=Socket.new(Socket::AF_INET,Socket::SOCK_DGRAM,0)
httpd.bind(Socket.pack_sockaddr_in(20000,“0.0.0.0”))

i=0

#httpd.setsockopt(:SOCKET,:SO_SNDBUF,1024000)

loop{
data=httpd.recvfrom(32768)
i+=1
p “#”+(i.to_s)+": received “+(data[0].size.to_s)+” bytes from
"+data[1].inspect_sockaddr
}
#####################################################################
#coding: utf-8

require “socket”

httpd=Socket.new(Socket::AF_INET,Socket::SOCK_DGRAM,0)
bin=File.new("…",“rb”)

httpd.setsockopt(:SOCKET,:SO_SNDBUF,1024000)
#p httpd.getsockopt(:SOCKET,:SO_SNDBUF)

ip=“127.0.0.1”

10000.times{|i|
httpd.send(bin.sysread(1024),0,Socket.pack_sockaddr_in(20000,ip))
#(sleep 0.001) if i%1==0
}

######################################################################

The main thing is that even with some dummy packets (and more threads -
more loss) i have huge loss.

For example: this sender sends 10000 packets without delays, but
receiver gets 2095 of packets. I tried to play with buffers but no luck.

With delays in 1 ms I have stable transmit rate but this is slow - 8
mbits. I’m able to run two such threads but more than that = huge loss
in packets.

Maybe someone also has this issue?

p.s. ruby 1.9.2 32 bit, windows

Mateus … wrote in post #1010062:

With delays in 1 ms I have stable transmit rate but this is slow - 8
mbits. I’m able to run two such threads but more than that = huge loss
in packets.

This is fundamental with UDP. It’s a non-guaranteed service. If you
flood buffers, packets will be lost.

You need to have some way to control the flow of data, and/or to
acknowledge packets. And at that point, you’re normally better off using
TCP.

What exactly are you trying to achieve? You know HTTP runs over TCP,
right? If this is local communication, would a Unix domain socket serve
you better?

Brian C. wrote in post #1010077:

Mateus … wrote in post #1010062:

With delays in 1 ms I have stable transmit rate but this is slow - 8
mbits. I’m able to run two such threads but more than that = huge loss
in packets.

This is fundamental with UDP. It’s a non-guaranteed service. If you
flood buffers, packets will be lost.

You need to have some way to control the flow of data, and/or to
acknowledge packets. And at that point, you’re normally better off using
TCP.

What exactly are you trying to achieve? You know HTTP runs over TCP,
right? If this is local communication, would a Unix domain socket serve
you better?

I’m just testing UDP performance on local machine. I need this for fast
interconnect between nodes in cluster, but even with local machine I
have poor performance.

I need conectionless protocol, so UDP seems to me like obvious proto,
but benchmark thinks different.

Also my testing machine has no traffic or cpu heavy tasks so 16 mbits
global bandwidth seems to me a bit tiny.

Brian C. wrote in post #1010102:

Mateus … wrote in post #1010080:

I’m just testing UDP performance on local machine. I need this for fast
interconnect between nodes in cluster, but even with local machine I
have poor performance.

I need conectionless protocol, so UDP seems to me like obvious proto,
but benchmark thinks different.

Your application doesn’t need reliable delivery of messages? Then what
you’ve shown is correct. If you throw N megabytes of data at UDP, but
have much less kernel buffer space available, or the receiver can’t
process it as fast as it arrives, then the kernel is forced to throw
packets away either at the sending side or the receiving side. It’s a
fact of life (and incidentally nothing to do with ruby).

It may be that the receive buffer is filling faster than you can empty
it: you could try removing the ‘puts’ from your receive program, and
just incrementing a counter instead.

But I think you should question why you have chosen a connectionless
protocol for this application. If you need to send large amounts of
data, but there’s some issue which makes TCP specifically unsuitable,
then perhaps SCTP would meet your needs better.

Thank You, Brian!
I removed “puts” and it seems that 85% of transmitted packets reached
destination.

Mateus … wrote in post #1010080:

I’m just testing UDP performance on local machine. I need this for fast
interconnect between nodes in cluster, but even with local machine I
have poor performance.

I need conectionless protocol, so UDP seems to me like obvious proto,
but benchmark thinks different.

Your application doesn’t need reliable delivery of messages? Then what
you’ve shown is correct. If you throw N megabytes of data at UDP, but
have much less kernel buffer space available, or the receiver can’t
process it as fast as it arrives, then the kernel is forced to throw
packets away either at the sending side or the receiving side. It’s a
fact of life (and incidentally nothing to do with ruby).

It may be that the receive buffer is filling faster than you can empty
it: you could try removing the ‘puts’ from your receive program, and
just incrementing a counter instead.

But I think you should question why you have chosen a connectionless
protocol for this application. If you need to send large amounts of
data, but there’s some issue which makes TCP specifically unsuitable,
then perhaps SCTP would meet your needs better.