Linux 异步 (io_submit) 写入 v/s 正常(缓冲)写入

标签 linux unix aio

既然写入是立即进行的(复制到内核缓冲区并返回),那么使用 io_submit 进行写入有什么好处?

事实上,它 (aio/io_submit) 看起来更糟,因为您必须在堆上分配写入缓冲区并且不能使用基于堆栈的缓冲区。

我的问题只是关于写入,而不是读取。

编辑:我说的是相对较小的写入(最多几 KB),而不是 MB 或 GB,因此缓冲区复制应该不是大问题。

最佳答案

将缓冲区复制到内核不一定是即时的。

首先内核需要找到一个空闲页面。如果没有(这很可能在沉重的磁盘写入压力下),它必须决定驱逐一个。如果它决定驱逐一个脏页(而不是驱逐你的进程),它必须在它可以使用该页面之前实际写入它。

当饱和写入慢速驱动器时,Linux 中存在一个相关问题,页面缓存会被慢速驱动器支持的脏页填满。每当内核出于任何原因需要一个页面时,都需要很长时间才能获取一个页面,结果整个系统会卡住。

与系统的写入压力相比,每个单独写入的大小更不相关。如果您有一百万个小写入已经排队,这可能是必须阻塞的一个。

关于分配是在栈上还是堆上也不太相关。如果您想要高效地分配要写入的 block ,您可以使用专用池分配器(来自堆),而不是为通用堆分配器付费。

aio_write() 通过根本不将缓冲区复制到内核中来解决这个问题,它甚至可能直接从缓冲区中 DMAd(考虑到对齐要求),这意味着您也可能保存副本。

关于Linux 异步 (io_submit) 写入 v/s 正常(缓冲)写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19419090/

相关文章:

linux - 对文本 Bash Linux 中的特定列使用 grep

python - wxPython 键绑定(bind)在 Linux 上不起作用

在 UNIX 中创建自定义选项

linux - unix bash - 保存环境变量和循环

linux - "Linux aio"和 "Linux native aio"是一回事吗?

c++ - io_getevents 在短于超时的时间内返回的作业数量少于请求的数量

regex - 如何从 Bash 中的正则表达式中提取多个环境变量?

c - 为什么 popen() 调用 shell 来执行进程?

linux - cron 作业部分运行

mysql - 没有 root 帐户无法在服务器上安装 MySQL 5.7