重置或释放写时复制映射区域的最快方法

Fastest way to reset or free copy-on-write mapped area

我有一个 CoW 内存区域,我需要将其重置为原始状态。

遗憾的是,MADV_DONTNEED 的行为与 munmap 完全相同,并且似乎正在释放所有页面。 munmap 非常昂贵并且性能至少可以说是可怕的,而且它的 way 使用 [=27 从头开始​​创建一个新的 $thing 更便宜=],手动初始化它,然后 munmap 那个。这对我来说毫无意义,只是表明 mmap 和 CoW 映射确实存在问题。不幸的是,我真的需要 CoW。就是从一个范围到另一个范围的那个或 memcpy,因为我们在 2021 年,我希望 Linux 能够进行写时复制。

参见:https://kostja.github.io/2012/04/04/1111.html

我只想丢弃内存范围内的脏页。

munmap anon: 435110ns (435 micros)
munmap memfd: 21958015ns (21958 micros)

这是释放 400x 128MB 范围时的平均时间。如果我只释放 1 个范围,那么我会得到合理的数字,所以内核中发生了某种我不理解的不良缩放。 tmpfs 支持的区域在使用 MAP_NORESERVE 分配后保持不变。这完全是疯了。 memfd (tmpfs-backed) 文件就那么慢吗?

最终最快的方法是使用硬件虚拟化本身来实现写时复制机制。它最终变得极其复杂,充满了脚枪,但最重要的是速度非常快。可以只使用几页工作内存来调用写时复制 VM。大多数页面都是重复页面 table 个条目。

此外,这开启了复制副本的可能性,以及扁平化写时复制 VM 以便它可以用作主服务器。

Linux 对此没有任何支持。