【问题标题】:How does the Linux kernel handle Asynchronous I/O (AIO) requests?Linux 内核如何处理异步 I/O (AIO) 请求?
【发布时间】:2015-03-12 00:10:09
【问题描述】:

我正在编写一个 C 程序,通过直接读取原始块设备文件来从 SSD 驱动器读取数据。

我正在尝试Linux AIO(我说的是Linux AIO API,即linuxaio.h提供的功能,例如io_submit(...)等,而不是POSIX AIO API)。我使用O_DIRECT 标志打开块设备文件,并确保写入缓冲区与块大小对齐。

我注意到 Linux AIO 比使用带有O_DIRECT 标志的同步 IO 快得多。

最让我吃惊的是,使用 Linux AIO 发出许多几 KB 的小随机读取所获得的吞吐量明显高于使用同步 I/ 进行几 MB 的大型(顺序)读取所获得的吞吐量O 和O_DIRECT

所以,我想知道:为什么 Linux AIO 的性能比同步 I/O 更好?使用 AIO 时内核做了什么?内核是否执行请求重新排序?与使用同步 I/O 相比,使用 Linux AIO 会导致更高的 CPU 利用率吗?

提前非常感谢

【问题讨论】:

  • AIO 更快,因为它的名字。它是异步的,基本上所有的 IO 都是对内存而不是底层磁盘完成的。
  • @Miline:这完全没有意义。从磁盘进行随机读取绝对需要来自磁盘的物理 I/O。没有办法将这些字节从磁盘魔术到内存中。
  • 我的意思是 IO 主要是从缓存数据的内存中完成的。将要写入的数据加载到内存中,然后将io返回给应用程序。并且内存中的那个页面被标记为脏。所以它的文件系统的工作是将该页面刷新到磁盘.. 在 DIRECTIO 的情况下.. io 在数据写入磁盘之前不会返回
  • @Miline linux kernel aio 需要O_DIRECT

标签: c linux io linux-kernel aio


【解决方案1】:

简答: AIO 实现很可能“更快”,因为它并行提交多个 IO,而同步实现有零个或一个正在运行的 I/O。它与写入内存或内核 I/O 路径对同步 I/O 有额外开销无关。

您可以使用 iostat -x -d 1 进行检查。查看 avgqu-sz(平均队列大小 = 进行中 I/O 的平均数量)和 %util(利用率 = 设备使用时间的百分比)至少有一个 I/O 发给它)。

长答案:

  • 在谈论 I/O 时,“更快”的概念很棘手。 “更快”是否意味着更高的带宽?还是更低的延迟?还是给定请求大小的带宽?还是给定队列深度的延迟?还是延迟、带宽、请求大小、队列深度和许多其他参数或工作负载的组合?我在这里假设您正在考虑吞吐量/带宽,但是,请记住,存储设备的性能不是单一维度的指标。

  • SSD 是高度并行的设备。 SSD由许多闪存芯片组成,每个芯片都有多个可以独立读取/写入的裸片。 SSD 利用这一点并并行执行许多 I/O,而响应时间没有明显增加。因此,就吞吐量而言,SSD 看到多少并发 I/O 非常重要。

  • 让我们了解当线程提交同步 I/O 时会发生什么:a) 线程花费一些 CPU 周期来准备 I/O 请求(生成数据、计算偏移量、将数据复制到缓冲区等), b) 执行系统调用(例如 pread()),执行传递到内核空间和线程块,c) I/O 请求由内核处理并遍历各个内核 I/O 层,d) I/O 请求提交给设备并遍历互连(例如 PCIe),e) I/O 请求由 SSD 固件处理,f) 实际读取命令发送到相应的闪存芯片,g) SSD控制器等待数据,h) SSD 控制器从闪存芯片获取数据并通过互连发送数据。此时数据离开 SSD,e-a) 阶段反向发生。

  • 如您所见,同步 I/O 进程正在与 SSD 进行请求乒乓球比赛。在上述许多阶段中,实际上没有从闪存芯片中读取数据。最重要的是,尽管您的 SSD 可以并行处理数十到数百个请求,但它在任何给定时间最多只能看到一个请求。因此,吞吐量非常非常低,因为您实际上并没有真正使用 SSD。

  • 异步 ​​I/O 有两种帮助:a) 它允许进程并行提交多个 I/O 请求(SSD 有足够的工作来保持忙碌),b) 它允许流水线化 I/O通过各个处理阶段(因此将阶段延迟与吞吐量分离)。

  • 您看到异步 I/O 比同步 I/O 快的原因是因为您比较苹果和橙子。同步吞吐量是在给定的请求大小、低队列深度且没有流水线的情况下实现的。异步吞吐量具有不同的请求大小、更高的队列深度和流水线。你看到的数字没有可比性。

  • 大多数 I/O 密集型应用程序(即大多数应用程序,如数据库、网络服务器等)都有许多执行同步 I/O 的线程。尽管每个线程在任何给定时刻最多可以提交一个 I/O,但内核和 SSD 设备会看到许多可以并行处理的 I/O 请求。多个同步 I/O 请求与多个异步 I/O 请求具有相同的好处。

    异步和同步 I/O 的主要区别在于 I/O 和进程的调度方式以及编程模型。如果操作正确,异步和同步 I/O 都可以从存储设备中压缩相同的 IOPS/吞吐量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2023-03-20
    相关资源
    最近更新 更多