以下のコードは機能し、正しいデータをすべて送信し、正しいデータを受信しています。
非常に高速なサーバーのベンチマークに使用すると、ベンチマークの CPU 使用率は ~10% です。ただし、遅いサーバーのベンチマークを行うと、ベンチマーク/ストレス テストを行っているサーバーと同じように、50% まで上昇します*。
それはtop
報告しているとおりです。
なぜそんなに多くのCPUを使用するのでしょうか? poll を悪用していると思われますが、方法がわかりません。
低速サーバーの 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 経由です。)