我有一个测试用例journalctl
,它花费几秒钟从磁盘读取。但是,如果我尝试对测试用例的多次运行进行基准测试,我会发现在第一次运行之后它的速度快得不可思议。即使我尝试删除缓存。为什么?
$ sync && echo 1 | sudo tee /proc/sys/vm/drop_caches && /usr/bin/time journalctl -b -u dev-shm.mount
1
0.01user 0.03system 0:04.50elapsed 1%CPU (0avgtext+0avgdata 30956maxresident)k
95424inputs+0outputs (424major+665minor)pagefaults 0swaps
$ sync && echo 1 | sudo tee /proc/sys/vm/drop_caches && /usr/bin/time journalctl -b -u dev-shm.mount >/dev/null
1
0.00user 0.01system 0:00.08elapsed 26%CPU (0avgtext+0avgdata 31832maxresident)k
94992inputs+0outputs (422major+445minor)pagefaults 0swaps
有趣time
的是,它仍然通过页面错误(inputs
)进行了大量的 IO。我注意到如果我跳过drop_caches
运行之间,它会显示 0。
drop_caches
只影响内核文件系统缓存。它不会影响底层硬件中的缓存。显然你的硬件有数百兆的缓存(94992 * 4096 ~= 400MB)。惊人的!就我而言,这是因为内核在 VM 中运行。所以“底层硬件”并不是一个简单的硬盘。这说明了
virt-manager
.用于“缓存模式”的选项尊重写入刷新(使用
fsync()
),但除此之外允许在主机内核的页面缓存中缓存写入和读取。“底层硬件”实际上包括主机 RAM 中的磁盘缓存,可能会增长到数 GB。libvirt / KVM 将此称为“写回”缓存。
我还注意到这加快了重新启动 VM 的速度。