When measuring UDP throughput between Windows PC and Zynq-based device by iperf2 tool, I am getting around 950 Mb/s over dedicated 1Gb Ethernet link. However, when using my own UDP application on PC I am getting only around 50 Mb/s, which is drastically lower throughput than measured by iperf. Of course, in my UDP application I don't have any processing, only while loop in which I am calling sendto function, with UDP packets of sizes of 1470 bytes. Application on Zynq device is provided by XAPP1026, so it's not mine. I am looking at iperf code trying to figure out what they do differently, but basically, I can't find any socket or udp options or anything similar they do in order to maximize UDP throughput.
Here is the code of the main function (MAXUDP define is 1470):
int main(int argc, char** argv)
{
int sockfd;
struct sockaddr_in servaddr;
char sendline[MAXUDP];
int i;
int j;
const int tr_size = ( 200 * MB );
const int npackets = ( tr_size / MAXUDP );
const int neval = 2;
DWORD start;
DWORD end;
int optval;
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 1), &wsaData) != 0 )
{
printf( "Err: %d\n", WSAGetLastError() );
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = inet_addr("172.16.0.215");
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
Connect(sockfd, (const SA*) &servaddr, sizeof(servaddr));
optval = 208*KB;
Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char*) &optval, sizeof optval);
prep_data(sendline, MAXUDP);
for ( i = 1; i <= neval; i++ )
{
start = GetTickCount();
for ( j = 0; j < npackets/neval; j++ )
sendto(sockfd, sendline, MAXUDP, 0, NULL, NULL);
end = GetTickCount() - start;
printf("Time elapsed: %d sec.\n", end/1000);
printf("Throughput: %d.%3d MB/s\n", (tr_size/neval)/end/1000, (tr_size/neval)/end - (tr_size/neval)/end/1000);
}
return 0;
}
So, my main question is how to maximize UDP throughput in the same way iperf does it?
UPDATE:
I switched to Ubuntu PC. Results are different, but still there is some random stuff happening.
The first thing I do is set IP addresses for eth0 (ifconfig eth0 172.16.0.200 netmask 255.255.255.0
) and gateway address (route add default gw 172.16.0.1
). When I run iperf with iperf -c 172.16.0.215 -i 5 -t 25 -u -b 1000m
) I am getting around 800 Mbits/sec. However, after few runs of iperf in same way, all of sudden I start getting only around 15 Mbits/sec or even much less. I figured out that I need to set IP, netmask and gateway addresses once again in order to get 800 Mbits/sec. Also, my UDP application behaves in the same way. I am measuring 957 Mbits/sec (with MAXUDP
set to 1470) after I had run commands for setting IP addresses. But after few iterations it slows down to around 11 Mbits/sec. Then I set IP addresses again, and the behavior repeats itself. So, as Kariem stated in his answer, the problem is not in the code itself, bur rather in some OS, netif configuration related stuff. However, I must run my UDP application on Windows, so I need to figure out what is happening there. If you guys have any ideas on what could be happening in Windows, please let me now.