C++内存映射的文件数据预取



我正在处理非常大的内存映射文件(200+GB),这些文件无法完全加载到内存中,并且是随机访问的。映射的文件存储在固态驱动器阵列上,但我仍然发现,除非之前进行过相同的搜索,并且使用的页面已经读取到内存中,否则一次访问一个所需部件的速度非常慢。

添加多个线程来同时读取mmap中的变量大大提高了速度,我在测试中无法达到改进的上限,但超过1000个线程会导致openmp抛出资源不可用的错误。

我也尝试过疯狂地向内核建议将需要的特定部分(MADV_WILNEED),但内核似乎没有足够快地按照建议行事,从而产生影响。

我正在寻找一种在实际使用之前同时预取所需数据部分的方法。读取变量(或包含该变量的映射文件的内存页面大小的部分)的资源密集度最低的方法是什么?强制将其放入内存而不阻塞读取。

如果无法避免阻塞,那么运行大量非常轻的线程来进行读取的方法也会起作用。

您似乎已经回答了自己的问题。除了线程之外,您唯一的解决方案是循环通过您可以为每个访问执行madvise的访问次数。然后,经过x个madvises(比如10000)后,您会返回并访问内存。但是,需要注意的是,O/S不能保证I/O将按照调用madvise的顺序进行。因此,O/S可能会处理第一个疯子,然后跳到疯子的末尾,或者地址最低的那个,基本上是随心所欲。根本没有办法将I/O速度大大提高到您想要的程度。

示例:

for(i=0; i < accesses + 10000; ++i)
{
madvise(access[i].addr, access[i].length, MADV_WILLNEED);
if(i >= 10000)
{
// Access location access[i-10000].addr
}
}

然而,如果您使用随机访问,您应该问问自己,内存映射这个文件是否真的是您想要做的。异步I/O似乎更有意义。

最新更新