最新版Linux中的TCP延迟较高
|
在我的研究小组中,我们最近将我们机器上的操作系统从Red Hat 6.2升级到Debian 8.3,并观察到我们机器之间通过集成Intel 1G NIC的TCP往返时间从大约110μs增加到220μs. 起初,我认为这是一个配置问题,所以我将所有sysctl配置(例如tcp_low_latency = 1)从未升级的Red Hat机器复制到Debian机器,并且没有解决问题.接下来,我认为这可能是Linux发行版问题并在机器上安装了Red Hat 7.2,但往返时间仍然在220μs左右. 最后,我想可能问题出在Linux内核版本上,因为Debian 8.3和Red Hat 7.2都使用了内核3.x而Red Hat 6.2使用了内核2.6.所以为了测试这个,我用Linux内核2.6和宾果游戏安装了Debian 6.0!时间再次快到110μs. 还有其他人在最新版本的Linux中经历过这些更高的延迟,是否有已知的解决方法? 最低工作实例 下面是一个C应用程序,可用于对延迟进行基准测试.它通过发送消息,等待响应,然后发送下一条消息来测量延迟.它使用100字节的消息执行此操作100,000次.因此,我们可以将客户端的执行时间除以100,000以获得往返延迟.要使用它,首先编译程序: g++ -o socketpingpong -O3 -std=c++0x Server.cpp 接下来在主机上运行应用程序的服务器端版本(例如,在192.168.0.101上).我们指定IP以确保我们在一个众所周知的界面上托管. socketpingpong 192.168.0.101 然后使用Unix实用程序时间来测量客户端的执行时间. time socketpingpong 192.168.0.101 client 在具有相同硬件的两个Debian 8.3主机之间运行此实验会得到以下结果. real 0m22.743s user 0m0.124s sys 0m1.992s Debian 6.0的结果是 real 0m11.448s user 0m0.716s sys 0m0.312s 码: #include <unistd.h>
#include <limits.h>
#include <string.h>
#include <linux/futex.h>
#include <arpa/inet.h>
#include <algorithm>
using namespace std;
static const int PORT = 2444;
static const int COUNT = 100000;
// Message sizes are 100 bytes
static const int SEND_SIZE = 100;
static const int RESP_SIZE = 100;
void serverLoop(const char* srd_addr) {
printf("Creating server via regular socketsrn");
int sockfd,newsockfd;
socklen_t clilen;
char buffer[SEND_SIZE];
char bufferOut[RESP_SIZE];
struct sockaddr_in serv_addr,cli_addr;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd < 0)
perror("ERROR opening socket");
bzero((char *) &serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(srd_addr);
serv_addr.sin_port = htons(PORT);
fflush(stdout);
if (bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
perror("ERROR on binding");
}
listen(sockfd,INT_MAX);
clilen = sizeof(cli_addr);
printf("Started listening on %s port %drn",srd_addr,PORT);
fflush(stdout);
while (true) {
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);
if (newsockfd < 0)
perror("ERROR on accept");
printf("New connectionrn");
int status = 1;
while (status > 0) {
// Read
status = read(newsockfd,buffer,SEND_SIZE);
if (status < 0) {
perror("read");
break;
}
if (status == 0) {
printf("connection closed");
break;
}
// Respond
status = write(newsockfd,bufferOut,RESP_SIZE);
if (status < 0) {
perror("write");
break;
}
}
close(newsockfd);
}
close(sockfd);
}
int clientLoop(const char* srd_addr) {
// This example is copied from http://www.binarytides.com/server-client-example-c-sockets-linux/
int sock;
struct sockaddr_in server;
char message[SEND_SIZE],server_reply[RESP_SIZE];
//Create socket
sock = socket(AF_INET,0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr(srd_addr);
server.sin_family = AF_INET;
server.sin_port = htons( PORT );
//Connect to remote server
if (connect(sock,(struct sockaddr *)&server,sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
printf("Connected to %s on port %dn",PORT);
// Fill buffer
for (int i = 0; i < SEND_SIZE; ++i) {
message[i] = 'a' + (i % 26);
}
for (int i = 0; i < COUNT; ++i) {
if (send(sock,message,SEND_SIZE,0) < 0) {
perror("send");
return 1;
}
if ( recv(sock,server_reply,RESP_SIZE,0) < 0) {
perror("recv");
return 1;
}
}
close(sock);
printf("Sending %d messages of size %d bytes with response sizes of %d bytesrn",COUNT,RESP_SIZE);
return 0;
}
int main(int argc,char** argv) {
if (argc < 2) {
printf("rnUsage: socketpingpong <ipaddress> [client]rn");
exit(-1);
}
if (argc == 2)
serverLoop(argv[1]);
else
clientLoop(argv[1]);
return 0;
}
解决方法这不是一个答案,但严格校准延迟/吞吐量问题非常重要.它可能会帮助您更接近答案,甚至帮助其他人在这里为您提供有关根本创建过程的更好建议.尝试通过接口上的wireshark / tshark捕获获得更准确的数据, >确认吞吐量实际减半>确定延迟的分布方式(在tx和rx之间)一个.在测试中它是否统一?湾在哪里有一个集中的摊位? (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
