【发布时间】:2014-01-26 13:00:59
【问题描述】:
下面的代码有效,它发送了所有正确的数据,并且接收了正确的数据。
当我用它来对一个速度非常快的服务器进行基准测试时,基准测试的 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 进行的。)
【问题讨论】:
-
我不太明白这个问题...如果你有一台更强大的计算机,很明显它比低端计算机更容易处理大量数据。这可以结束:在“高性能”计算机上更快地完成或“一次”完成但在低性能上使用更多 CPU。
-
@SergiCastellsaguéMillán 这一切都在同一台计算机上,都在同一个 CPU 内核上。 “慢速服务器”和“快速服务器”之间的唯一区别是,一个是庞大的慢速代码库,开销很大,一个是我新的、轻量级的重写。
-
服务器是否仅在完整消息后才回复?如果是这样...
-
.revents = POLLIN | POLLOUT你不应该设置它,而不是do-while只是让它更好while(poll(pollfd,...))循环。此外,AFAIKPOLLIN意味着您需要阅读,而不是写作,POLLOUT也是如此。 -
@user9000 我正在设置它,并使用
do...while,因为它几乎可以保证在第一次循环中被读/写。
标签: c linux posix poll-syscall