By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,947 Members | 1,594 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,947 IT Pros & Developers. It's quick & easy.

UDP performance

P: n/a
I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).

I must be doing something wrong and would really appreciate feedback on
my code below:

I open the server port with

self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((myaddress, myport))

I then open a client port with

self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect((host, port))

the client sends data with

self.s.sendall(data)

and the server with

self.s.sendto(data,link.remoteaddress)

both receive with

buf, address = socket.recvfrom(8192)

The sender and receiver are in separate threads (threading.Thread).

Does anyone know what is going wrong here, the socket communication, the
thread scheduling?

Paul Sijben

Apr 20 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a

Paul Sijben wrote:
I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).
[snip]
buf, address = socket.recvfrom(8192)


I'm not an expert here, but I AFAIK UDP packet size should be kept
below 512 bytes otherwise it can cause fragmentation and hence all the
slow stuff like acknoledgements, timeouts, etc...

Apr 20 '06 #2

P: n/a
Serge Orlov wrote:
Paul Sijben wrote:
I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).


[snip]
buf, address = socket.recvfrom(8192)


I'm not an expert here, but I AFAIK UDP packet size should be kept
below 512 bytes otherwise it can cause fragmentation and hence all the
slow stuff like acknoledgements, timeouts, etc...

good point in general but in practice they are in this case. but this is
less of a problem on the loopback interface anyway.
Apr 20 '06 #3

P: n/a

Paul Sijben wrote:
Serge Orlov wrote:
Paul Sijben wrote:
I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).


[snip]
buf, address = socket.recvfrom(8192)


I'm not an expert here, but I AFAIK UDP packet size should be kept
below 512 bytes otherwise it can cause fragmentation and hence all the
slow stuff like acknoledgements, timeouts, etc...

good point in general but in practice they are in this case. but this is
less of a problem on the loopback interface anyway.


Isn't it still controlled by MTU even on the loopback? What is your MTU
on the loopback?

Apr 20 '06 #4

P: n/a
Serge Orlov wrote:
Paul Sijben wrote:
Serge Orlov wrote:
Paul Sijben wrote:
I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).
[snip]

buf, address = socket.recvfrom(8192)
I'm not an expert here, but I AFAIK UDP packet size should be kept
below 512 bytes otherwise it can cause fragmentation and hence all the
slow stuff like acknoledgements, timeouts, etc...

good point in general but in practice they are in this case. but this is
less of a problem on the loopback interface anyway.


Isn't it still controlled by MTU even on the loopback? What is your MTU
on the loopback?

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1

eth0 Link encap:Ethernet HWaddr 00:14:85:35:A4:5D
inet addr:192.168.0.124 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::214:85ff:fe35:a45d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

Apr 20 '06 #5

P: n/a
Paul Sijben wrote:
I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).

I must be doing something wrong and would really appreciate feedback on
my code below:

I open the server port with

self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((myaddress, myport))

I then open a client port with

self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect((host, port))

the client sends data with

self.s.sendall(data)

and the server with

self.s.sendto(data,link.remoteaddress)

both receive with

buf, address = socket.recvfrom(8192)

The sender and receiver are in separate threads (threading.Thread).

Does anyone know what is going wrong here, the socket communication, the
thread scheduling?

Paul Sijben


Is the connection 1:1 i.e. the receiving end receives data only from one
sender at the time? And how do you handle lost packages in your application?

--
mph
Apr 20 '06 #6

P: n/a
Martin P. Hellwig wrote:
[snip]
Is the connection 1:1 i.e. the receiving end receives data only from one
sender at the time? And how do you handle lost packages in your
application?


no the server is receiving from multiple clients.

and at the moment I do not handle lost packets.
Apr 20 '06 #7

P: n/a
OK the problem I posted about earlier is NOT a UDP/socket problem, it is
a threading problem. Albeit one that only happens when you have many
thrreads????

I have made two little scripts using the code I copied below, one client
and one server (attached).

If I run them concurrently on the same machine I see the following times:
1145526192.825508 <<1145526192.825848
1145526193.829325 <<1145526193.834927

a transfer time in the milliseconds. Much less than the times I see in
the full application.

OK so I put them both in a multithreaded script (also attached)

1145526971.619558 <<1145526971.619909
1145526972.619241 <<1145526972.619647

again transfer time in milliseconds.

Not like this that I get from the profile of my code:
<< 1145517554.363850 send 1145517554.647485 recv

which uses the same communication and threading but has 20+ threads?

Now I am completely baffled!

again I really appreciate if anyone can shed light on this!

Paul
Paul Sijben wrote: I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).

I must be doing something wrong and would really appreciate feedback on
my code below:

I open the server port with

self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((myaddress, myport))

I then open a client port with

self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect((host, port))

the client sends data with

self.s.sendall(data)

and the server with

self.s.sendto(data,link.remoteaddress)

both receive with

buf, address = socket.recvfrom(8192)

The sender and receiver are in separate threads (threading.Thread).

Does anyone know what is going wrong here, the socket communication, the
thread scheduling?

Paul Sijben


import socket
import time

profile=[]

s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('127.0.0.1', 42420))
print ">>%f"%time.time()
s.sendall('testerdetest')
time.sleep(1)
print ">>%f"%time.time()
s.sendall('testerdetest')
print ">>%f"%time.time()
import socket
import time

profile=[]
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 42420))
buf, address =s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
buf, address =s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address

import socket
import time
import threading
profile=[]

class server(threading.Thread):
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind(('', 42420))
threading.Thread.__init__(self)
self.start()

def run(self):
buf, address =self.s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
buf, address =self.s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address

class client(threading.Thread):
def __init__(self):
self.s =socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect(('127.0.0.1', 42420))
threading.Thread.__init__(self)
self.start()

def run(self):
print ">>%f"%time.time()
self.s.sendall('testerdetest')
time.sleep(1)
print ">>%f"%time.time()
self.s.sendall('testerdetest')
print ">>%f"%time.time()
serv=server()
cl=client()

Apr 20 '06 #8

P: n/a
I found that the problem was caused by the sending thread not giving
control back quickly enough to the receiving thread.

Also in going through the code I found an old self.s.setblocking(0)call
that was no longer relevant. Removing that solved my problem.

Something that took 20 seconds now takes just 1.

Thanks to those who took the time to respond to my earlier messages.

Paul

Paul Sijben wrote:
OK the problem I posted about earlier is NOT a UDP/socket problem, it is
a threading problem. Albeit one that only happens when you have many
thrreads????

I have made two little scripts using the code I copied below, one client
and one server (attached).

If I run them concurrently on the same machine I see the following times:
1145526192.825508 <<1145526192.825848
1145526193.829325 <<1145526193.834927

a transfer time in the milliseconds. Much less than the times I see in
the full application.

OK so I put them both in a multithreaded script (also attached)

1145526971.619558 <<1145526971.619909
1145526972.619241 <<1145526972.619647

again transfer time in milliseconds.

Not like this that I get from the profile of my code:
<< 1145517554.363850 send 1145517554.647485 recv


which uses the same communication and threading but has 20+ threads?

Now I am completely baffled!

again I really appreciate if anyone can shed light on this!

Paul
Paul Sijben wrote:
I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).

I must be doing something wrong and would really appreciate feedback on
my code below:

I open the server port with

self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((myaddress, myport))

I then open a client port with

self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect((host, port))

the client sends data with

self.s.sendall(data)

and the server with

self.s.sendto(data,link.remoteaddress)

both receive with

buf, address = socket.recvfrom(8192)

The sender and receiver are in separate threads (threading.Thread).

Does anyone know what is going wrong here, the socket communication, the
thread scheduling?

Paul Sijben


------------------------------------------------------------------------

import socket
import time

profile=[]

s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('127.0.0.1', 42420))
print ">>%f"%time.time()
s.sendall('testerdetest')
time.sleep(1)
print ">>%f"%time.time()
s.sendall('testerdetest')
print ">>%f"%time.time()

------------------------------------------------------------------------

import socket
import time

profile=[]
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 42420))
buf, address =s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
buf, address =s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
------------------------------------------------------------------------

import socket
import time
import threading
profile=[]

class server(threading.Thread):
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind(('', 42420))
threading.Thread.__init__(self)
self.start()

def run(self):
buf, address =self.s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
buf, address =self.s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address

class client(threading.Thread):
def __init__(self):
self.s =socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect(('127.0.0.1', 42420))
threading.Thread.__init__(self)
self.start()

def run(self):
print ">>%f"%time.time()
self.s.sendall('testerdetest')
time.sleep(1)
print ">>%f"%time.time()
self.s.sendall('testerdetest')
print ">>%f"%time.time()
serv=server()
cl=client()

Apr 20 '06 #9

P: n/a
OK the problem I posted about earlier is NOT a UDP/socket problem, it is
a threading problem. Albeit one that only happens when you have many
thrreads????

I have made two little scripts using the code I copied below, one client
and one server (attached).

If I run them concurrently on the same machine I see the following times:
1145526192.825508 <<1145526192.825848
1145526193.829325 <<1145526193.834927

a transfer time in the milliseconds. Much less than the times I see in
the full application.

OK so I put them both in a multithreaded script (also attached)

1145526971.619558 <<1145526971.619909
1145526972.619241 <<1145526972.619647

again transfer time in milliseconds.

Not like this that I get from the profile of my code:
<< 1145517554.363850 send 1145517554.647485 recv

which uses the same communication and threading but has 20+ threads?

Now I am completely baffled!

again I really appreciate if anyone can shed light on this!

Paul
Paul Sijben wrote: I am stumped by the following problem. I have a large multi-threaded
server accepting communications on one UDP port (chosen for its supposed
speed).

I have been profiling the code and found that the UDP communication is
my biggest drain on performance! Communication where the client and the
server are on the same machine still takes 300ms or sometimes much more
per packet on an Athlon64 3000+ running Linux (Fedora Core 5 x64).

I must be doing something wrong and would really appreciate feedback on
my code below:

I open the server port with

self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((myaddress, myport))

I then open a client port with

self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect((host, port))

the client sends data with

self.s.sendall(data)

and the server with

self.s.sendto(data,link.remoteaddress)

both receive with

buf, address = socket.recvfrom(8192)

The sender and receiver are in separate threads (threading.Thread).

Does anyone know what is going wrong here, the socket communication, the
thread scheduling?

Paul Sijben

import socket
import time

profile=[]

s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('127.0.0.1', 42420))
print ">>%f"%time.time()
s.sendall('testerdetest')
time.sleep(1)
print ">>%f"%time.time()
s.sendall('testerdetest')
print ">>%f"%time.time()

import socket
import time

profile=[]
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 42420))
buf, address =s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
buf, address =s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
import socket
import time
import threading
profile=[]

class server(threading.Thread):
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind(('', 42420))
threading.Thread.__init__(self)
self.start()

def run(self):
buf, address =self.s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address
buf, address =self.s.recvfrom(8192)
print "<<%f"%time.time()
print buf, address

class client(threading.Thread):
def __init__(self):
self.s =socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.connect(('127.0.0.1', 42420))
threading.Thread.__init__(self)
self.start()

def run(self):
print ">>%f"%time.time()
self.s.sendall('testerdetest')
time.sleep(1)
print ">>%f"%time.time()
self.s.sendall('testerdetest')
print ">>%f"%time.time()
serv=server()
cl=client()
Apr 20 '06 #10

P: n/a
In article <44***********************@news.xs4all.nl>,
Paul Sijben <si****@eemvalley.com> wrote:
I found that the problem was caused by the sending thread not giving
control back quickly enough to the receiving thread.

Also in going through the code I found an old self.s.setblocking(0)call
that was no longer relevant. Removing that solved my problem.

Something that took 20 seconds now takes just 1.


You might also find that it goes still faster if you forego threading
and use a select.select loop.
Apr 22 '06 #11

P: n/a
Lawrence D'Oliveiro wrote:
In article <44***********************@news.xs4all.nl>,
Paul Sijben <si****@eemvalley.com> wrote:
I found that the problem was caused by the sending thread not giving
control back quickly enough to the receiving thread.

Also in going through the code I found an old self.s.setblocking(0)call
that was no longer relevant. Removing that solved my problem.

Something that took 20 seconds now takes just 1.


You might also find that it goes still faster if you forego threading
and use a select.select loop.


thanks for that. I will have to try it.
Apr 25 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.