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 11 4632
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...
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.
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?
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
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
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.
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()
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()
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()
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.
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. This discussion thread is closed Replies have been disabled for this discussion. Similar topics
25 posts
views
Thread by Brian Patterson |
last post: by
|
12 posts
views
Thread by Fred |
last post: by
|
12 posts
views
Thread by serge |
last post: by
|
6 posts
views
Thread by teedilo |
last post: by
|
5 posts
views
Thread by Scott |
last post: by
|
115 posts
views
Thread by Mark Shelor |
last post: by
|
13 posts
views
Thread by bjarne |
last post: by
|
13 posts
views
Thread by Bern McCarty |
last post: by
|
7 posts
views
Thread by Michael D. Ober |
last post: by
|
1 post
views
Thread by jvn |
last post: by
| | | | | | | | | | |