msync 性能是否取决于所提供范围的大小?

Quo*_*han 2 memory-management mmap linux-kernel

我正在对映射文件进行许多小的随机写入。我想确保一致性,所以有时我会使用msync,但我不想跟踪我所做的每一个小写入。msync在当前的 Linux 内核实现中,使用整个文件是否会带来性能损失?例如,如果文件是 100GB,但我总共只做了 10MB 的更改?内核是否循环遍历提供的范围内的每个页面msync以查找要刷新的脏页面,或者这些页面是否保存在某种链接列表/其他结构中?

Mar*_*lli 5

TL;DR:不,不是,保存所需信息的内核结构旨在使操作高效,无论范围大小如何。

可映射对象的页面保存在基数树中,但是基数树的 Linux 内核实现还有一个额外的特殊功能:可以用最多 3 个不同的标记来标记条目,并且可以更快地找到和迭代标记的条目。实际使用的数据结构称为“XArray”,您可以在这篇 LWN 文章或 中找到有关它的更多信息Documentation/core-api/xarray.rst

脏页有一个特殊的标记,可以设置(PAGECACHE_TAG_DIRTY),以便在需要写回时可以快速找到它们(例如msyncfsync等)。此外,XArray 提供了一种 O(1) 机制来检查是否存在带有给定标记的任何条目,因此,对于页而言,即使在查找脏页之前也可以快速确定是否需要回写。

msync总之,在调用整个映射(而不是仅调用较小范围的实际修改的页面)时,您不应遭受明显的性能损失。