6

我正在阅读这篇关于异步磁盘文件 I/O 的教程,但是它并没有让事情变得清晰,它实际上让我更加困惑。

有两种不同的异步。根据教程的 I/O 模型:

  1. 异步阻塞 I/O,您使用.打开文件O_ASYNC,然后使用epoll// 。pollselect

  2. 使用 glibc 的 AIO 的异步 IO

由于 glibc 使用线程池实现 AIO,所以我在这个问题中用“AIO”指的是内核 AIO,即io_submit

至少从概念上看,似乎没有太大区别——io_submit可以让你发出多个 I/O 请求,而另一方面,readO_ASYNC你一起使用可以只发出一个带有文件位置的请求。

本指南还提到使用epoll作为 Linux AIO 的替代方案:

民意调查。Linux对用作异步 I/O 机制的支持有限。epoll对于以缓冲模式打开的文件(即没有O_DIRECT)的读取,如果文件以 方式打开O_NONBLOCK,则读取将返回 EAGAIN 直到相关部分在内存中。对缓冲文件的写入通常是立即的,因为它们是通过另一个写回线程写出的。但是,这些机制并没有提供直接 I/O 提供的对 I/O 的控制级别。

epoll用作 AIO 替代品有什么问题?或者换句话说,我们需要[新界面]io_submit解决的问题是什么?

4

1 回答 1

1

在我看来,io_* api 背后的关键问题是通过 2 个主要措施实现更高 IO 吞吐量的能力:

  1. 最小化应用程序 IO 循环中的系统调用次数。可以提交多个请求批次,然后在稍后的某个时间,应用程序可以返回以使用 io_getevents() 一次性检查单​​个请求的结果。重要的是,io_getevents() 将返回有关每个单独的 IO 事务的信息,而不是 epoll() 在每次调用时返回的模糊的“fd x 有未决更改”信息位。

  2. 内核 IO 调度程序可以依靠请求重新排序来更好地利用硬件。应用程序甚至可以传递一些关于如何使用 struct iocb 中的 aio_reqprio 字段重新排序请求的提示。必然地,如果我们允许对 IO 请求重新排序,我们需要为应用程序提供适当的 API 来查询某些特定的高优先级请求是否已经完成(因此是 io_getevents())。

可以说,io_getevents() 是真正重要的功能,因此 io_submit() 是有效使用它的便捷伴侣。

于 2013-10-31T03:18:07.213 回答