![为什么 NetBSD grep 在后续调用中速度减慢近 15 倍](https://linux22.com/image/188130/%E4%B8%BA%E4%BB%80%E4%B9%88%20NetBSD%20grep%20%E5%9C%A8%E5%90%8E%E7%BB%AD%E8%B0%83%E7%94%A8%E4%B8%AD%E9%80%9F%E5%BA%A6%E5%87%8F%E6%85%A2%E8%BF%91%2015%20%E5%80%8D.png)
我正在研究 APUE 中的示例。在 NetBSD 9.0 系统上,在没有大负载的情况下,我对调用进行计时grep
并得到了一个不起眼的结果:
apue$ cd /usr/include
apue$ time -p grep __POSIX_SOURCE */*.h > /dev/null
real 0.73
user 0.01
sys 0.63
但是,如果我多次重复该实验,系统时间会急剧增加(高达 15 倍):
apue$ time -p grep _POSIX_SOURCE */*.h > /dev/null
real 0.57
user 0.02
sys 0.54
apue$ time -p grep _POSIX_SOURCE */*.h > /dev/null
real 10.06
user 0.01
sys 10.04
apue$ time -p grep _POSIX_SOURCE */*.h > /dev/null
real 3.57
user 0.01
sys 3.56
apue$ time -p grep _POSIX_SOURCE */*.h > /dev/null
real 4.58
user 0.00
sys 4.58
apue$ time -p grep _POSIX_SOURCE */*.h > /dev/null
real 5.56
user 0.02
sys 5.53
apue$ time -p grep _POSIX_SOURCE */*.h > /dev/null
real 6.57
user 0.00
sys 6.56
apue$ time -p grep _POSIX_SOURCE */*.h > /dev/null
real 2.56
user 0.01
sys 2.54
这是预期的行为吗?是什么导致了如此大的差异?
更新 根据@Tim 给出的答案,我查看了我的 Buffercache,发现当 grep 正在努力进行搜索时,它已完全分配为 100%。重新启动虚拟机后,缓冲区使用率下降至 95% 左右。
$ sysstat bufcache
/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10
Load Average |
603 metadata buffers using 5565 kBytes of memory ( 0%).
15512 pages for cached file data using 62048 kBytes of memory ( 3%).
3034 pages for executables using 12136 kBytes of memory ( 1%).
6460 pages for anon (non-file) data 25840 kBytes of memory ( 1%).
468172 free pages 1872688 kBytes of memory (93%).
File System Bufs used % kB in use % Bufsize kB % Util %
/ 577 95 5378 97 5418 97 99
Total: 577 95 5378 97 5418 97 99
答案1
是否可能耗尽读取缓存(文件系统缓冲区缓存;参考 buffercache(9))?
在第一遍中,缓存主要是空的,因此刚刚添加页面。一旦缓存已满,就需要执行某种 LRU(最近最少使用)算法,以确定需要从缓存中逐出哪些页面。该代码需要(额外的)时间来完成其工作。
在执行这些测试时监视内存状态,看看速度减慢是否与可用内存达到零同时发生。