gpt4 book ai didi

c - Linux :Identifying pages in memory

转载 作者:IT王子 更新时间:2023-10-29 00:59:06 25 4
gpt4 key购买 nike

我想知道一个大文件的哪一部分缓存在内存中。我正在使用来自 fincore 的一些代码为此,它是这样工作的:文件被映射,然后 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;
}

最佳答案

表示列表所需的信息量是,对于所有或几乎所有页面确实在 RAM 中的悲观情况,比位图高得多 - 每个条目至少 64 比 1 位。如果有这样的 API,当查询它关于你的 20 亿个页面时,你将不得不准备在回复中获得 16 GB 的数据。此外,处理可变长度结构(例如列表)比处理固定长度数组更复杂,因此库函数(尤其是低级系统函数)往往会避免麻烦。

我也不太确定实现(在这种情况下操作系统如何与 TLB 和 Co 交互),但很可能(即使大小差异除外)填充位图可以比创建位图更快地执行由于从中提取信息的操作系统级和硬件级结构而列出。

如果您不关心非常精细的粒度,您可以看看 /proc/<PID>/smaps .对于每个映射区域,它会显示一些统计信息,包括加载到内存中的数量(Rss 字段)。如果出于调试目的,您使用单独的 mmap() 映射文件的某些区域调用(除了用于执行实际任务的主要映射),您可能会在 smaps 中获得单独的条目从而查看这些地区的单独统计数据。您几乎肯定无法在不破坏系统的情况下进行数十亿次映射,但如果文件结构良好,也许仅对几十个精心挑选的区域进行单独统计可以帮助您找到所需的答案。

关于c - Linux :Identifying pages in memory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11364613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com