Linux:识别内存中的页面

waz*_*oox 6 c linux

我想知道一个巨大的文件的哪个部分被缓存在内存中.我正在使用fincore的一些代码,这样就可以了:文件是mmaped,然后fincore循环遍历地址空间并使用mincore检查页面,但由于文件大小(几TB),它很长(几分钟) ).

有没有办法循环使用的RAM页面呢?它会快得多,但这意味着我应该从某个地方获取已用过的页面列表...但是我找不到一个方便的系统调用来实现这一点.

代码如下:

#include <errno.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 
/* } */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/sysinfo.h>


void
fincore(char *filename) {
   int fd;
   struct stat st;

   struct sysinfo info;
   if (sysinfo(& info)) {
    perror("sysinfo");
    return;
   }

   void *pa = (char *)0;
   char *vec = (char *)0;
   size_t pageSize = getpagesize();
   register size_t pageIndex;

   fd = open(filename, 0);
   if (0 > fd) {
      perror("open");
      return;
   }

   if (0 != fstat(fd, &st)) {
      perror("fstat");
      close(fd);
      return;
   }

   pa = mmap((void *)0, st.st_size, PROT_NONE, MAP_SHARED, fd, 0);
   if (MAP_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, st.st_size, 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;
}
Run Code Online (Sandbox Code Playgroud)

小智 0

由谁缓存?

考虑启动后文件位于磁盘上。它的任何部分都不在内存中。

现在打开文件并执行随机读取。

文件系统(例如内核)将被缓存。

C 标准库将进行缓存。

内核将缓存在内核模式内存中,C 标准库缓存在用户模式内存中。

如果您可以发出查询,也可能是在查询之后(在返回给您之前)立即从缓存中删除有问题的缓存数据。