Linux

在 mmap 區域中順序/隨機讀取時出現奇怪的主要頁面錯誤數

  • February 9, 2020

我正在關注這個答案,試圖產生一些主要的頁面錯誤mmap

#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>

int main(int argc, char ** argv) {
 int fd = open(argv[1], O_RDONLY);
 struct stat stats;
 fstat(fd, &stats);
 posix_fadvise(fd, 0, stats.st_size, POSIX_FADV_DONTNEED);
 char * map = (char *) mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0);
 if (map == MAP_FAILED) {
   perror("Failed to mmap");
   return 1;
 }
 int result = 0;
 int i;
 for (i = 0; i < stats.st_size; i++) {
   result += map[i];
 }
 munmap(map, stats.st_size);
 return result;
}

我試圖映射一個1.6G文件然後讀取但只發生了1主要的頁面錯誤。

Major (requiring I/O) page faults: 1
Minor (reclaiming a frame) page faults: 38139

當我隨機讀取數據時

// hopefully this won't trigger extra page faults
unsigned int idx = 0;
for (i = 0; i < stats.st_size; i++) {
 result += map[idx % stats.st_size];
 idx += i;
}

頁面錯誤激增至16415

Major (requiring I/O) page faults: 16415
Minor (reclaiming a frame) page faults: 37665

是否有類似在核心中預取來預載入mmap數據的東西?我怎麼能用/usr/bin/timeor來告訴這個perf

我正在使用gcc 6.5.0和。Ubuntu 18.04``4.15.0-54-generic

是的,預設情況下核心會預讀(您所謂的預取),請參閱https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/filemap.c? h=v5.5#n2476

您可以通過使用建議呼叫posix_madvise()after來禁用此記憶體區域的預讀。mmap()``POSIX_MADV_RANDOM

引用自:https://unix.stackexchange.com/questions/533811