我一直在测试不同的方法来缩短编译整个 C++ 项目所需的时间。目前大约需要 5 分钟。我尝试了 distcc、ccache 等。最近,我发现如果我将整个项目复制到 RAM 驱动器上,然后从那里进行编译,编译时间将减少到原始时间的 30%,只需 1.5 分钟。
显然,从 RAM 驱动器工作是不切实际的。那么,有谁知道我可以用什么方法强制操作系统始终缓存某个目录?我仍然希望目录像平常一样同步回磁盘,但我总是希望内存中的数据副本。这可能吗?
编辑:
作为一种可能的解决方案,我们只是想到启动一个rsync
每隔 10 秒左右运行一次的守护进程,以将磁盘驱动器与 RAM 驱动器同步。然后我们从 RAM 驱动器运行编译。速度rsync
非常快,但这真的有用吗?当然操作系统可以做得更好......
答案1
将一堆文件保留在缓存中的明显方法是经常访问它们。 Linux 非常擅长在交换和缓存之间进行仲裁,因此我怀疑您观察到的速度差异实际上并不是由于操作系统没有将内容保留在缓存中,而是由于您使用 tmpfs 和其他尝试之间的其他差异。
尝试观察每种情况下正在执行 IO 的操作。基本工具是iotop
。其他工具可能有用;看Linux 磁盘 IO 负载细分(按文件系统路径和/或进程)?,Linux 中的什么程序可以测量一段时间内的 I/O?,以及服务器故障中的其他线程。
以下是关于可能发生的情况的一些假设。如果您进行测量,请展示它们,以便我们可以证实或反驳这些假设。
答案2
Linux默认情况下使用 RAM 作为磁盘缓存。作为演示,尝试运行time find /some/dir/containing/a/lot/of/files > /dev/null
两次,第二次要快得多,因为每个磁盘 inode 都被缓存了。这里的重点是如何利用这个内核功能并阻止您替换它的尝试。
重点是要改变swappiness
.让我们考虑三种主要的内存使用类型:活动程序、非活动程序和磁盘缓存。显然,活动程序使用的内存不应该被换出,并且其他两个之间的选择是相当任意的。您想要快速的程序切换还是快速的文件访问? A低交换性更喜欢将程序保留在内存中(即使长时间不使用)和高互换性更喜欢保留更多磁盘缓存(通过交换未使用的程序)。 (交换范围为 0 到 100,默认值为 60)
我对你的问题的解决方案是将交换性更改为非常高(90-95,而不是100)并加载缓存:
echo 95 | sudo tee /proc/sys/vm/swappiness > /dev/null # once after reboot
find /your/source/directory -type f -exec cat {} \; > /dev/null
正如您所猜测的,您必须有足够的可用内存来缓存所有源文件和目标文件以及编译器,包括头文件、链接库、IDE 和其他使用的程序。
答案3
如果我想将某些文件或某个目录中的所有文件保留在缓存中,这个东西似乎对我有用。
虚拟触摸似乎就是这么做的。示例5可能有你需要的。
vmtouch -dl /whatever/directory/
我需要以root身份运行它sudo
答案4
inosync
如果您要 rsync 到 ramdisk,该守护进程听起来就像您想要的那样。它不是每 10 秒左右进行一次 rsync,而是使用 Linux 的 inotify 工具在文件更改时进行 rsync。我在 Debian 存储库中找到了它的inosync
软件包,或者它的源代码可以在http://bb.xnull.de/projects/inosync/。