提问人:Steve Wu 提问时间:10/15/2023 最后编辑:Peter CordesSteve Wu 更新时间:10/15/2023 访问量:29
为什么将 rg(ripgrep) 与 mmap 一起使用会触发更多次要页面错误?
Why using rg(ripgrep) with mmap triggers more minor page faults?
问:
我使用 rg + perf 来衡量 mmap 性能与 pread,用作性能指标。结果如下:minor page fault
mmap
perf stat -e major-faults,minor-faults rg -j1 -F 123 a-big-file --mmap
0 major-faults
509 minor-faults
0.002241400 seconds time elapsed
0.000000000 seconds user
0.002221000 seconds sys
无 MMAP
perf stat -e major-faults,minor-faults rg -j1 -F 123 a-big-file --no-mmap
0 major-faults
396 minor-faults
0.002911774 seconds time elapsed
0.002890000 seconds user
0.000000000 seconds sys
grep 针对空文件
性能计数器统计信息:rg -j1 -F 123 empty_file --mmap
0 major-faults
393 minor-faults
0.001652534 seconds time elapsed
0.000000000 seconds user
0.001648000 seconds sys
似乎使用 mmap 会导致更多的页面错误,有没有人知道如何对 Linux 进行深度跟踪,以便可以显示导致轻微页面错误的代码?目前我的怀疑是munmap。
答:
当您第一次触摸 mmaped 区域时,使用读取大文件通常涉及软(次要)页面错误,除非您使用(如果 pagecache 中尚未热,它也会等待 I/O,因此大多数程序不希望这样做。mmap
MAP_POPULATE
故障(当一个页面出现故障时,将相邻页面连接到页表中)使故障成本通常不会太差。内核应该注意到页面错误中的顺序读取模式,并连接多个页面,而不仅仅是出错的页面。
madvise(MADV_SEQUENTIAL)
可能会有所帮助,或者可能只对磁盘的 I/O 有所帮助。从另一个线程执行操作可能是个好主意;IDK 我没有测试过。 在初始 mmap 上,它的缺点是不允许 mmap 返回,因此您甚至无法开始读取文件,并且无法将计算与 I/O 重叠。但是,让内核检查页面并将它们连接到页表中,同时执行您正在执行的任何操作可能会有所帮助。MADV_POPULATE_READ
MAP_POPULATE
perf record -e page-faults
应该能够记录故障指令。由于您的程序不会触发任何主要的页面错误(必须休眠以进行 I/O,因为您的大文件不会太大以至于内核无法将其保持在页面缓存中),因此唯一的页面错误将是次要错误。
(我没有对此进行测试,并且 IDK 事件的默认样本粒度是多少;IDK,如果它默认会记录每个页面错误的样本。page-faults
评论