我想知道一个巨大的文件的哪个部分被缓存在内存中.我正在使用fincore中的一些代码,它以这种方式工作:文件被mmaped,然后fincore循环遍历地址空间并使用mincore检查页面,但由于文件大小(几TB),它很长(几分钟) ).
有没有办法循环使用的RAM页面呢?它会快得多,但这意味着我应该从某个地方获取已用过的页面列表…但是我找不到一个方便的系统调用来实现这一点.
代码如下:
#include dio.h>
#include Failed == pa) {
perror("mmap");
close(fd);
return;
}
/* vec = calloc(1,1+st.st_size/pageSize); */
/* 2.2 sec for 8 TB */
vec = calloc(1,(st.st_size+pageSize-1)/pageSize);
if ((void *)0 == vec) {
perror("calloc");
close(fd);
return;
}
/* 48 sec for 8 TB */
if (0 != mincore(pa,vec)) {
fprintf(stderr,"mincore(%p,%lu,%p): %s\n",pa,(unsigned long)st.st_size,vec,strerror(errno));
free(vec);
close(fd);
return;
}
/* handle the results */
/* 2m45s for 8 TB */
for (pageIndex = 0; pageIndex <= st.st_size/pageSize; pageIndex++) {
if (vec[pageIndex]&1) {
printf("%zd\n",pageIndex);
}
}
free(vec);
vec = (char *)0;
munmap(pa,st.st_size);
close(fd);
return;
}
int main(int argc,char *argv[]) {
fincore(argv[1]);
return 0;
}
最佳答案
表示列表所需的信息量,对于悲观情况,当所有或几乎所有页面确实在RAM中时,远高于位图 – 每个条目至少64比1比特.如果有这样的API,当查询它的20亿页时,你必须准备好在回复中获得16 GB的数据.此外,处理可变长度结构(如列表)比处理固定长度数组更复杂,因此库函数(尤其是低级系统函数)往往可以避免麻烦.
我也不太确定实现(在这种情况下操作系统如何与TLB和Co交互),但很可能(除了大小差异)填写位图可以比创建列表更快地执行从中提取信息的OS和硬件级结构.
如果您不关心非常精细的粒度,可以查看/ proc /< PID> / smaps.对于每个映射区域,它显示一些统计信息,包括加载到内存中的数量(RSS字段).如果为了调试的目的,您使用单独的mmap()调用映射文件的某些区域(除了用于执行实际任务的主映射),您可能会在smaps中获得单独的条目,因此可以看到这些条目的单独统计信息区域.你几乎肯定无法在不杀死你的系统的情况下制作数十亿的映射,但如果文件结构良好,可能只为几十个精心挑选的区域提供单独的统计数据可以帮助你找到你想要的答案.