在 mmap 区域中顺序/随机读取时出现奇怪的主要页面错误数

在 mmap 区域中顺序/随机读取时出现奇怪的主要页面错误数

我正在跟进这个答案,尝试使用以下命令生成一些主要页面错误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.044.15.0-54-generic

答案1

是的,内核默认会进行预读(您称为预取),请参阅https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/filemap.c?h=v5.5#n2476

posix_madvise()您可以通过调用aftermmap()并提供建议来禁用此内存区域的预读POSIX_MADV_RANDOM

相关内容