0

下面的代码有效,它正在发送所有正确的数据,并且正在接收正确的数据。

当我用它对一个非常快的服务器进行基准测试时,基准测试的 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 进行的。)

4

3 回答 3

1

原因是你正忙着等待。如果readandwrite返回EAGAIN或者EWOULDBLOCK您正在连续调用它们。添加一个select它将等到套接字准备好读取或写入之前。

于 2014-01-26T13:19:54.230 回答
0

问题解决了。

它并没有准确地歪曲 CPU 使用率。效率低下的服务器使用 TCP_NODELAY 发送 8 字节数据包,因此我收到数百万条轮询通知,只读取 8 个字节。事实证明 read(2) 调用相当昂贵,每秒调用数万次就足以让“在系统模式下花费的时间”飙升至约 56%,这被添加到“在用户模式下花费的时间”中" 以产生非常高的 CPU 使用率。

于 2014-01-26T14:37:32.883 回答
0

所以如果我终于明白了,你是在比较%CPUtop 报告的比率与top 报告的增长率的比率TIME+,他们不同意。(如果你说你从哪一列读取会更容易!)据我所知,两者都是从基础/proc数据中的相同字段计算出来的,所以他们不可能有太大的分歧。

我无法复制它。我已将您的代码放入测试程序并在没有修改的情况下运行它,除了修复int r编译错误的重新声明并为您遗漏的所有内容添加我认为合理的声明。我将它连接到一个服务器,该服务器从客户端读取线路,并在每条线路之后消耗一点 CPU,然后再发送一条线路。结果是,top 显示%CPU大约 99 个服务器和 2 个客户端,TIME+列中的比率约为 50:1。

我发现使用poll.

我不喜欢你的使用assert——当断言被关闭时,程序会丢失很多重要的系统调用。

于 2014-01-26T17:33:52.797 回答