我试图从高端存储设备的 Linux 块驱动程序中获得最大的性能。目前让我有点难过的一个问题是:如果用户任务在一个 CPU 上启动 I/O 操作(读或写),而设备中断发生在另一个 CPU 上,我会在此之前产生大约 80 微秒的延迟任务恢复执行。
我可以对原始块设备使用 O_DIRECT 看到这一点,因此这与页面缓存或文件系统无关。驱动程序用于make_request
接收操作,因此它没有请求队列并且不使用任何内核 I/O 调度程序(您必须相信我,这种方式更快)。
我可以向自己证明,在调用bio_endio
一个 CPU 和在另一个 CPU 上重新安排任务之间会出现问题。如果任务在同一个 CPU 上,它会很快启动,如果任务在另一个物理 CPU 上,则需要更长的时间——在我当前的测试系统上通常要多 80 微秒(Intel 5520 [NUMA] 芯片组上的 x86_64 )。
通过将进程和 IRQ cpu 关联设置为相同的物理 CPU,我可以立即将性能翻倍,但这不是一个好的长期解决方案——无论 I/O 来自何处,我都希望能够获得良好的性能。而且我只有一个 IRQ,所以我一次只能将它引导到一个 CPU —— 如果多个线程在多个 CPU 上运行,那就不好了。
我可以在从 Centos 5.4 的 2.6.18 到主线 2.6.32 的内核上看到这个问题。
bio_endio
所以问题是:如果我从另一个 CPU调用,为什么用户进程需要更长的时间才能恢复?这是调度程序问题吗?有什么办法可以消除或降低延迟?