Linux kernel 为什么在跨越CPU时块I/O完成需要如此长的时间?

Linux kernel 为什么在跨越CPU时块I/O完成需要如此长的时间?,linux-kernel,linux-device-driver,smp,Linux Kernel,Linux Device Driver,Smp,我正试图从高端存储设备的Linux块驱动程序中获得最大的性能。目前让我有点困惑的一个问题是:如果一个用户任务在一个CPU上启动I/O操作(读或写),而设备中断发生在另一个CPU上,那么在任务恢复执行之前,我会产生大约80微秒的延迟 我可以使用O_直接针对原始块设备看到这一点,因此这与页面缓存或文件系统无关。驱动程序使用make_request来接收操作,因此它没有请求队列,也不使用任何内核I/O调度程序(您必须相信我,这样做速度更快) 我可以向自己证明,在一个CPU上调用bio_endio和在另

我正试图从高端存储设备的Linux块驱动程序中获得最大的性能。目前让我有点困惑的一个问题是:如果一个用户任务在一个CPU上启动I/O操作(读或写),而设备中断发生在另一个CPU上,那么在任务恢复执行之前,我会产生大约80微秒的延迟

我可以使用O_直接针对原始块设备看到这一点,因此这与页面缓存或文件系统无关。驱动程序使用
make_request
来接收操作,因此它没有请求队列,也不使用任何内核I/O调度程序(您必须相信我,这样做速度更快)

我可以向自己证明,在一个CPU上调用
bio_endio
和在另一个CPU上重新调度任务之间会出现问题。如果任务在同一个CPU上,则启动速度非常快,如果任务在另一个物理CPU上,则需要更长的时间——在我当前的测试系统(英特尔5520[NUMA]芯片组上的x86_64)上通常需要80微秒

通过将进程和IRQ cpu关联设置为同一物理cpu,我可以立即将性能提高一倍,但这不是一个好的长期解决方案——我更希望无论I/O来自何处都能获得良好的性能。而且我只有一个IRQ,所以我一次只能将它引导到一个CPU上——如果许多线程在多个CPU上运行,那就不好了

我可以在Centos 5.4的2.6.18到主线2.6.32的内核上看到这个问题


所以问题是:如果我从另一个CPU调用
bio_endio
,为什么用户进程需要更长的时间才能恢复?这是调度程序问题吗?有没有办法消除或降低延迟?

如果您在特定的CPU上完成I/O,那么该处理器可以立即开始处理新线程-如果您在与请求它的线程相同的处理器上完成I/O,那么下一个线程很可能就是您为其完成I/O的线程

另一方面,如果您在另一个处理器上完成,请求i/o的线程将不会立即运行—它必须等待当前执行的任何线程完成其量程或以其他方式放弃CPU


据我所知。

如果您在特定的CPU上完成I/O,那么该处理器可以立即自由地开始处理一个新线程-如果您在与请求它的线程相同的处理器上完成I/O,那么下一个线程很可能就是您为其完成I/O的线程

另一方面,如果您在另一个处理器上完成,请求i/o的线程将不会立即运行—它必须等待当前执行的任何线程完成其量程或以其他方式放弃CPU


据我所知。

这可能只是从完成bio的CPU向调度任务的CPU发出IPI的固有延迟——为了测试这一点,试着用
idle=poll

引导可能只是从完成bio的CPU向调度任务的CPU发出IPI的固有延迟-为了测试这一点,试着用
idle=poll

引导看起来我有点误解了这个问题:它似乎与缓存未命中有关;当处理中断的cpu不是启动i/o的cpu时,cpu会达到100%的利用率,然后一切都会变慢,给人的印象是cpu之间的通信有很长的延迟


感谢大家的想法。

看起来我有点误解了这个问题:它似乎与缓存未命中有关;当处理中断的cpu不是启动i/o的cpu时,cpu会达到100%的利用率,然后一切都会变慢,给人的印象是cpu之间的通信有很长的延迟

感谢大家的想法。

刚刚发布到LKML,在块设备层实现了
队列\u标志\u相同的\u CPU
,描述如下:

添加标志以使请求在上完成 提交请求的cpu。这个 标志表示
队列\u标志\u相同\u组合
。通过 默认情况下,它处于关闭状态

听起来它可能正是您所需要的…

刚刚发布到LKML,在块设备层实现了
队列\u标志\u相同的\u CPU
,描述如下:

添加标志以使请求在上完成 提交请求的cpu。这个 标志表示
队列\u标志\u相同\u组合
。通过 默认情况下,它处于关闭状态


听起来这可能正是你所需要的…

这是个好主意,我将对此进行调查;然而,在我的测试期间,我只运行IO绑定的线程,所以大多数时候不应该有任何其他可运行的进程;然而,在我的测试期间,我只运行IO绑定的线程,所以大多数时候不应该有任何其他可运行的进程。它给了我一个微小的性能提升(2-3%),但似乎没有影响主要问题(将性能减半)。有趣的想法。它给了我一个微小的性能提升(2-3%),但似乎并没有影响主要问题(将性能减半)。是的,我正沿着这些思路思考,但我不愿意加入更多的猜测。它很可能是一个从一个缓存跳转到另一个缓存的锁(可能是任务锁?)。但实际上,听起来你需要做一些设置,这样每次中断都会有更多的IO。没有锁,只有大量的IO。还有一个NUMA系统,它使得跨cpu的未命中非常昂贵。更大的传输更好,但有时你不得不接受内核或应用程序提供给你的东西。是的,我一直在考虑这些问题,但我不愿意插嘴更多的猜测。它很可能是一个从一个缓存跳转到另一个缓存的锁(可能是任务锁?)。真的,听起来像你