我正在跟进这个答案,尝试使用以下命令生成一些主要页面错误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/time
or来判断这一点perf
?
我正在使用gcc 6.5.0
和。Ubuntu 18.04
4.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
。