我发现一个带有 io_submit 延迟的非常奇怪的问题。
如果我编写一个循环调用 io_submit 5 次,如下所示:
for (int i = 0; i < 5; i++) {
gettimeofday(&start);
io_submit(...);
gettimeofday(&end);
}
io_submit 的延迟都非常小,除了第一个
io_submit cost: 9 us
io_submit cost: 2 us
io_submit cost: 2 us
io_submit cost: 3 us
但是如果我在每次调用 io_submit 后睡觉,就像下面这样:
for (int i = 0; i < 5; i++) {
gettimeofday(&start);
io_submit(...);
gettimeofday(&end);
sleep(1);
}
io_submit 的延迟都非常大:
io_submit cost: 9 us
io_submit cost: 8 us
io_submit cost: 9 us
io_submit cost: 7 us
块设备是 nvme ssd。我曾尝试使用 blktrace,但似乎 blktrace 与 nvme 有一些问题,仅捕获事件 'Q' 和 'A',这不足以弄清楚这个问题。我也尝试使用 systemtap 来跟踪 io_submit 代码中的某个点,但这使得 io_submit 的延迟变得太大,接近 50us,这使得上层情况之间的差异不明显。
有谁知道为什么会这样或给出一些建议来解决这个问题。
新进展:
使用 systemptap,我发现延迟的增加来自代码路径的许多地方,而不是一个地方。两件事情。首先,上下文切换带来的cpu cache miss,睡眠情况导致更多的上下文切换;其次,代码路径分配然后释放内存,如果不休眠运行,本轮释放的内存可以在下一轮重用。而在睡眠状态下,刚刚空闲的内存可能会被其他线程使用。