【问题标题】:Why submitting pwrite request using io_submit API is much slower than submitting pread request?为什么使用 io_submit API 提交 pwrite 请求比提交 pread 请求慢得多?
【发布时间】:2016-08-05 09:00:40
【问题描述】:

我有一个从磁盘读取大量数据并写入大量数据的应用程序。我正在尝试使用直接 io 来提高 I/O 性能。

现在我使用libaio 来实现异步 IO,用于读取和写入。初步结果显示,阅读阶段有所改善,但写作阶段大幅下降。

然后我使用strace 捕获运行时行为,这里是阅读阶段日志(我删除了一些不相关的日志):

8509  20:59:03.005920 io_submit(139876672323584, 16, {{pread, filedes:102, buf:0x7f36bf816000, nbytes:524288, offset:96468992}} <unfinished ...>
8509  20:59:03.007236 <... io_submit resumed> ) = 16 <0.000893>

这是写作阶段的日志:

8098  20:47:40.219194 io_submit(140277578346496, 1, {{pwrite, filedes:116, str:"\177\362\215\264\252\360\240\306\377?\265\36/\215#%\304\0343\300\230\256\3550\374 k\316\v\225\327\""..., nbytes:524288, offset:24117248}}) = 1 <0.002457>

通常相同的io_submit API 需要不同的时间。即使一次提交 16 个读请求,它仍然比提交 1 个写请求快。

所以对吗?如何优化我的写入阶段?

【问题讨论】:

  • 写比读慢也就不足为奇了。根据很多参数(文件系统,支持技术,...),您可以重新分配内存(并因此找到新位置),可能在重写之前有一个缓慢的擦除阶段,...。相反,读取是一个“简单”的访问请求。
  • 什么文件系统?什么磁盘控制器?什么磁盘?磁盘是如何分区的?有 RAID 阵列吗?那是怎么配置的?磁盘 IO 操作是否与磁盘块对齐?
  • 在你的操作系统上使用任何异步 i/o 的另一种方法是简单地使用内存映射文件部分。将文件 B 截断到正确的大小,在文件 A 和文件 B 中映射,调用 memcpy(),如果文件很大,则在滑动 10Mb 窗口中进行映射。在几乎所有操作系统上,这将执行最高效的 i/o 模式,已投入大量内核调整以确保出色的性能。

标签: c++ io aio


【解决方案1】:

您是否使用O_DIRECT 打开您的文件,并且您是否将 a 写入完全分配的文件?如果没有,那么io_submit() 可以很容易地开始花费很长时间,基本上变成了阻塞调用。请参阅answers to asynchronous IO io_submit latency in Ubuntu Linux 之一,了解为使io_submit() 正常执行必须执行的一些操作。

【讨论】:

    猜你喜欢
    • 2018-08-29
    • 2017-02-22
    • 1970-01-01
    • 2010-11-27
    • 2016-08-28
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多