【发布时间】:2015-07-31 10:45:17
【问题描述】:
我想将两个进程之间的 Unix 域套接字的性能与另一个 IPC 的性能进行比较。
我有一个创建套接字对然后调用 fork 的基本程序。然后,它测量 RTT 以将 8192 字节发送到另一个进程并返回(每次迭代都不同)。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
int main(int argc, char **argv) {
int i, pid, sockpair[2];
char buf[8192];
struct timespec tp1, tp2;
assert(argc == 2);
// Create a socket pair using Unix domain sockets with reliable,
// in-order data transmission.
socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair);
// We then fork to create a child process and then start the benchmark.
pid = fork();
if (pid == 0) { // This is the child process.
for (i = 0; i < atoi(argv[1]); i++) {
assert(recv(sockpair[1], buf, sizeof(buf), 0) > 0);
assert(send(sockpair[1], buf, sizeof(buf), 0) > 0);
}
} else { // This is the parent process.
for (i = 0; i < atoi(argv[1]); i++) {
memset(buf, i, sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
assert(clock_gettime(CLOCK_REALTIME, &tp1) == 0);
assert(send(sockpair[0], buf, sizeof(buf), 0) > 0);
assert(recv(sockpair[0], buf, sizeof(buf), 0) > 0);
assert(clock_gettime(CLOCK_REALTIME, &tp2) == 0);
printf("%lu ns\n", tp2.tv_nsec - tp1.tv_nsec);
}
}
return 0;
}
但是,我注意到对于每个重复测试,第一次运行的经过时间 (i = 0) 始终是异常值:
79306 ns
18649 ns
19910 ns
19601 ns
...
我想知道内核是否必须在第一次调用send() 时进行一些最终设置——例如,在内核中分配8192 字节来缓冲调用send() 和recv() 之间的数据?
【问题讨论】:
-
可能是这样,也可能与调度器中的时间有关。
-
顺便说一句,在计算
struct timespec差异时,您可能不想忘记tv_sec。当第二个增加并且您将负纳秒差异格式化为%lu时,这将看起来像一个 大 数字。
标签: c performance sockets unix benchmarking