我想创建一个C ++服务器/客户端,它可以最大化我的localhost上TCP套接字通信的吞吐量。作为准备工作,我使用iperf来了解i7 MacBookPro上的最大带宽。
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 256 KByte (default)
------------------------------------------------------------
[ 4] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 51583
[ 4] 0.0-120.0 sec 329 GBytes 23.6 Gbits/sec
没有任何调整,ipref告诉我,我可以达到至少23.2 GBit / s。然后我做了自己的C ++服务器/客户端实现,你可以在这里找到完整的代码:https://gist.github.com/1116635
我的代码我基本上每次读/写操作传输一个1024bytes的int数组。所以我在服务器上的发送循环如下所示:
int n;
int x[256];
//fill int array
for (int i=0;i<256;i++)
{
x[i]=i;
}
for (int i=0;i<(4*1024*1024);i++)
{
n = write(sock,x,sizeof(x));
if (n < 0) error("ERROR writing to socket");
}
我在客户端上的接收循环如下所示:
int x[256];
for (int i=0;i<(4*1024*1024);i++)
{
n = read(sockfd,x,((sizeof(int)*256)));
if (n < 0) error("ERROR reading from socket");
}
正如标题中所提到的,运行它(使用-O3编译)会导致以下执行时间大约为3 GBit / s:
./client 127.0.0.1 1234
Elapsed time for Reading 4GigaBytes of data over socket on localhost: 9578ms
我在哪里放宽了带宽,我做错了什么?同样,完整的代码可以在这里看到:https://gist.github.com/1116635
感谢任何帮助!
答案 0 :(得分:5)
答案 1 :(得分:3)
您可以使用strace -f iperf -s localhost
找出iperf的不同做法。它似乎比你使用了更大的缓冲区(131072字节大,2.0.5)。
此外,iperf
使用多个线程。如果你有4个CPU内核,在客户端和服务器上使用两个线程将导致性能大约翻倍。
答案 2 :(得分:3)
我之前的回答是错误的。我测试了你的程序,结果如下。
0m7.763s
0m5.209s
0m3.780s
我只更改了客户端。我怀疑如果你也改变了服务器,可以挤压更多的性能。
我得到的结果与你所做的完全不同(0m7.763s
vs 9578ms
)也表明这是由执行的系统调用次数引起的(因为我们有不同的处理器......)。要挤出更多的表现:
readv
和writev
)splice(2)
,sendfile(2)
答案 3 :(得分:1)
如果您确实希望获得最高性能,请使用mmap
+ splice/sendfile
,对于localhost通信,请使用unix域流套接字(AF_LOCAL
)。