PDA

View Full Version : UDP Performance bad



tigertap
17th March 2008, 08:19
Hello,

i've programmed a test-application in QT4-3-4 for Windows (Commercial eval for VS2003) to get maximum UDP-throghput.
The application is a simple receiver, that gets UDP-datagrams and calculates throughput. We also have a sender (written in C, WinAPI) and several receivers (C, C#, Java...). Now we are testing QT's performance. With C, WSA, we got results of astonishing 900-950MBit/s.
The QT-application has two threads, one for GUI and one only for receiving. I used QUdpSocket-class, but results were as bad as 35-40MBit/s.
What is wrong it?? Has anyone same experiences??
Here is how i did it (only the receiving function in the 2nd thread):


void sTestThread::run()
{
quint32 dgs = 0;

started = true;
initRecv();
while ( started )
{
psock->waitForReadyRead( 20 );
if ( psock->hasPendingDatagrams() )
{
fill = psock->pendingDatagramSize();
psock->readDatagram( buffer, MAX_UDPSIZE, 0, 0 );
dgs++;
checkDg();
}
}
deinitRecv();
}


regards and thanks

tigertap

wysota
17th March 2008, 15:28
The socket is owned by a wrong thread thus you are wasting time on thread synchronization. Instead create the socket in the run() method of the thread, it should get faster then. And don't use waitForReadyRead() - use signals and slots instead. You'll be able to get rid of the other thread then additionally speeding up your application (remember, threads slow down applications on single cpu systems and not make them faster).

tigertap
17th March 2008, 15:42
Hello,

The socket is created inside initRecv() (sorry, i did not tell) in the run(), so it should be in the right thread.
Why not use waitForReadyRead()? Is it slow??

thanks

tigertap

wysota
17th March 2008, 15:47
Why not use waitForReadyRead()? Is it slow??
It increases the cpu usage and causes the thread to block, thus reducing the power of the whole system. If you don't block, you can handle a single socket in the main thread using signals and slots, this should increase performance of your program. I don't know if the change would be signification for you, but maybe it's worth to try...

tigertap
17th March 2008, 16:03
Hmm, yes, I think I know what you mean.
But the intention was to run the GUI-thread standalone from the receiving. This was part of the test-scenario. The tests are running on multicore-machines, hopefully QT distributes them on the processors. (with WinAPI, i know there is a function called SetProcessorAffinity() or something like that).
What makes me wonder, is the huge difference between the C WinAPI, C# and C with QT in throughputs. The receiver applications are all done in the same way, one thread for GUI, one only for receive. C, C# allow 900-950MBit/s with moderate loss, Java is slightly more worse, but C with QT.

One thing that I can't set in QUdpSocket is the buffer size. At the moment I'm trying to program the app in QT3, to set the buffer size. For 1GBit/s it should be 2.5MB to have enough space to collect datagrams in one Windows-slice of 20ms. I think that the problem is lying somewhere in here.

regards
tigertap

wysota
17th March 2008, 16:53
But the intention was to run the GUI-thread standalone from the receiving.
I understand. Nevertheless you have a busy waiting loop that is completely redundant.


The tests are running on multicore-machines, hopefully QT distributes them on the processors. (with WinAPI, i know there is a function called SetProcessorAffinity() or something like that).
Qt has nothing to do with that. It assumes the operating system "knows better", so threads might be scheduled to the same processing unit. You should be able to verify that using system monitoring tools.


What makes me wonder, is the huge difference between the C WinAPI, C# and C with QT in throughputs. The receiver applications are all done in the same way, one thread for GUI, one only for receive. C, C# allow 900-950MBit/s with moderate loss, Java is slightly more worse, but C with QT.
You may use a profiler to find the bottleneck. Seems that you are not reading data fast enough, but why - that I don't know.