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

Does msync performance depend on the size of the provided range?

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

TL;DR:不,它不是,保留所需信息的内核结构旨在使操作高效,而不管范围大小。

可映射对象的页面保存在 radix tree, however the Linux kernel implementation of radix trees has an additional special feature: entries can be marked with up to 3 different marks, and marked entries can be found and iterated on a lot faster. The actual data structure used is called "XArray", you can find more information about it in this LWN article or in Documentation/core-api/xarray.rst

脏页有一个可以设置的特殊标记(PAGECACHE_TAG_DIRTY),以便在需要回写时可以快速找到它们(例如msyncfsync等)。此外,XArrays 提供了一种 O(1) 机制来检查是否存在具有给定标记的任何条目,因此在页面的情况下,甚至可以在查找脏页之前快速确定是否需要回写。

总而言之,在整个映射上调用 msync 与仅对一小部分实际修改的页面调用相比,您不应招致明显的性能损失。