下面的代码有效,它发送所有正确的数据,并且它正在接收正确的数据。
当我使用它来测试非常快的服务器时,基准测试的CPU使用率约为10%。但是,当我对一台慢速服务器进行基准测试时,它会上升到~50% - 与我正在进行基准测试/压力测试的服务器相同*。
这是top
报告的内容。
为什么会使用这么多CPU?我怀疑我在滥用民意调查,但我不确定如何?
慢速服务器的CPU时间是基准测试的4倍,而快速服务器的CPU时间是基准测试的7倍。
int flags = fcntl(sockfd, F_GETFL, 0);
assert(flags != -1);
assert(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) != -1);
int32 red = 0;
struct pollfd pollfd = {
.fd = sockfd,
.events = POLLIN | POLLOUT
};
do {
assert(poll(&pollfd, 1, -1) == 1);
if (pollfd.revents & POLLOUT) {
int n;
while ((n = send(sockfd, buf__+bufOffset, bufLength-bufOffset, MSG_NOSIGNAL)) > 0) {
bufOffset += n;
if (n != bufLength-bufOffset)
break;
}
assert(!(n == -1 && errno != EAGAIN && errno != EWOULDBLOCK));
}
if (pollfd.revents & POLLIN) {
int r;
while ((r = read(sockfd, recvBuf, MIN(recvLength-red, recvBufLength))) > 0) {
// assert(memcmp(recvBuf, recvExpectedBuf+red, r) == 0);
red += r;
if (r != MIN(recvLength-red, recvBufLength))
break;
}
assert(!(r == -1 && errno != EAGAIN && errno != EWOULDBLOCK));
}
} while (bufOffset < bufLength);
assert(fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK) != -1);
int r;
while ((r = read(sockfd, recvBuf, MIN(recvLength-red, recvBufLength))) > 0) {
// assert(memcmp(recvBuf, recvExpectedBuf+red, r) == 0);
red += r;
}
assert(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) != -1);
assert(red == recvLength);
int r = read(sockfd, recvBuf, 1);
assert((r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) || r == 0);
*(我现在在同一台机器上运行基准测试和服务器。通信是通过TCP进行的。)
答案 0 :(得分:1)
原因是你在忙着等待。如果read
和write
返回EAGAIN
或EWOULDBLOCK
,则表示您正在连续调用它们。添加一个select
,它将等待套接字准备好在此之前读取或写入。
答案 1 :(得分:0)
问题解决了。
并没有完全错误地表示CPU使用情况。效率低下的服务器使用TCP_NODELAY发送8字节包,所以我收到了数百万个轮询通知,只读取8个字节。事实证明,read(2)调用相当昂贵,并且每秒调用它数万次就足以看到“在系统模式下花费的时间”火箭达到~56%,这被添加到“用户模式花费的时间” “产生非常高的CPU使用率。
答案 2 :(得分:0)
因此,如果我最终理解了这一点,那么您要比较top报告的%CPU
与top报告的TIME+
增长率的比率,他们不同意。 (如果你说的是你正在阅读哪些列,那会更容易!)据我所知,两者都是从底层/proc
数据中的相同字段计算的,所以它们不可能不同意见。
我无法复制它。我已将您的代码放入测试程序并运行它,除了修复int r
编译错误的重新声明,并添加我认为对您遗漏的所有内容的合理声明。我将它连接到一个服务器,该服务器从客户端读取行并在每个行之后吃掉一点CPU,然后再发回一行。结果是,顶部显示%CPU
约为99,服务器为2,客户端为2,TIME+
列约为50:1。
我发现使用poll
没有错。
我不喜欢你使用assert
- 当断言被关闭时,程序会丢失许多重要的系统调用。