【问题标题】:io_submit() blocks until a previous operation will be completedio_submit() 阻塞直到前一个操作完成
【发布时间】:2015-07-02 03:51:51
【问题描述】:

我是通过libaio使用Linux kernel AIO,在上一个读操作完成之前,我必须提交下一个读操作。问题是io_submit() 阻塞了一段时间,我可以从间隔中推断出,它等待上一个操作完成。

我知道我可以用一个 io_submit() 将多个操作排入队列,但这对我来说不是一个选项,因为我不知道下一个读取操作到底会如何,因为已经到了提交第一个。

它是只对我有用,还是对所有人有用?在第二种情况下,请问我是在寻找可行的方法,还是必须回退到线程模型?

【问题讨论】:

  • io_submit 会在奇怪的、不可预测的条件下阻塞(这就是我不使用它的原因)。我曾经四处询问并得到类似“当然,它必须以这种方式工作,有一个有限大小的请求队列”的答案。发生这种情况,例如做一个大的请求可能会被分解成几个较小的请求,所以......队列已满并阻塞。线程化 glibc 异步 I/O 实现效果更好,但要注意它会按需生成线程(如果不能接受,请使用您自己的工作池)。
  • 还要注意,如果不关闭缓冲,无论如何内核aio都会同步运行。一个允许缓冲异步 I/O 的补丁(由某个印度人开发)已经存在了十年左右,但基于“没人需要”而被拒绝。
  • 在我使用它时,我看到它阻塞了几十微秒,偶尔会在 100-200us 范围内出现短暂的现象,但没有比它更高的了。尽管如此,将它放在它自己的线程中就足够了。如果您的阻塞时间超过此时间,请确保您使用 O_DIRECT 打开并且您使用的是 512 字节对齐的内存缓冲区(和长度)。此外,如果您对文件系统上的文件执行此操作,请确保文件系统支持它。这很棘手!
  • 我正在使用支持它的 ext4。您是否尝试在第一个操作未完成时执行第二个 io_submit()?
  • 两年后我再次偶然发现了这一点,并注意到提到了“ext4”。请注意,ext4 根本不真的 支持 aio(或者相反,aio 不支持 ext4)。即使您“正确”地做所有事情(O_DIRECT,这是一个主要的反优化和对齐读取),您仍然可能有 io_submit 块。如果出于某种原因需要读取文件系统元数据,这将在io_submit 内阻塞,而您不走运。可悲的是,阻塞并等待一次搜索与等待传输几兆字节大致相同,因此这使得 aio 有点毫无意义。

标签: c linux aio


【解决方案1】:

令人沮丧的是,io_submit 可能会阻止的原因有很多,包括:

  • 您正在执行缓冲 I/O
  • 您正在对文件系统执行 I/O,并且您的提交在同步操作后面排队。

已知ext4 and AIO may not be the best mix:

在 ext4 上的 io_submit、缓冲操作、网络访问、管道等上阻塞。 [...] 部分支持对文件系统(如 ext4)上文件的 AIO 访问:如果读取元数据需要查找数据块(即,如果元数据尚未在内存中),则 io_submit 调用将阻塞读取的元数据。某些类型的文件放大写入完全不受支持,并在整个操作期间阻塞。

(摘自一个名为 AIOUserGuide 的文档)

有关其他详细答案,请参阅asynchronous IO io_submit latency in Ubuntu Linux 问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多