【发布时间】:2022-12-09 21:39:49
【问题描述】:
我正在映射一个巨大的文件,以避免我的应用程序抖动到主虚拟内存,并能够使用超过我拥有的 RAM 运行该应用程序。代码是 c++,但部分遵循旧的 c API。当我使用分配的指针时,内存确实会根据需要返回到文件中。但是,当我下次运行该应用程序时,我希望从已经具有准备好的数据的同一个文件中读取内存。出于某种原因,在下一次运行中,我读回了所有零。我究竟做错了什么?是 ftruncate 调用吗?是带有错误标志的 fopen 调用吗?是 mmap 标志吗?
int64_t mmbytes=1<<36;
FILE *file = fopen(filename, "w+");
int fd = fileno(file);
int r = ftruncate(fd, mmbytes );
if (file == NULL || r){
perror("Failed: ");
throw std::runtime_error(std::strerror(errno));
} //
if ((mm = mmap(0, mmbytes,
PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0)) == MAP_FAILED)
{
fprintf(stderr,"mmap error for output, errno %d\n", errno);
exit(-1);
}
}
【问题讨论】:
-
读取文件的代码在哪里?您的矩阵有多大(以字节为单位),它是否等于
mmbytes和sizeof(mymatrix) * DIM?是的,以写入模式打开文件然后从中读取是一个问题。 -
另请注意,映射一个大文件只会将内存抖动移动到程序中的不同位置(即在读/写时)
-
"w+"如果文件已经存在则采取行动:销毁内容 - 参见std::fopen -
1) 添加了 mmbytes 值。 2) 是的,会有一些颠簸,但访问是按顺序按大块进行的,大约每分钟前进到下一个块。 3)所以? fopen with "r+" 是吗?
-
按顺序访问大块,每分钟左右前进到下一个块这只是使用
mmap()的最次优方式。mmap()是慢的,特别是对于只读取一次数据的顺序读取。如果文件大于内存,你将要破坏你的虚拟机。只需将open()与O_DIRECT、read()数据一起使用,并绕过页面缓存,因为数据大于内存,缓存它是没有用的。