2

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

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

我还尝试过 madvise 向内核建议将需要的特定部分(MADV_WILLNEED),但内核似乎没有足够快地按照建议采取行动以产生影响。

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

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

4

1 回答 1

2

你似乎已经回答了你自己的问题。除了线程之外,您唯一的解决方案是循环遍历您可以madvise为每个执行的许多访问。然后在一些 x 数量的madvises(比如 10,000)之后,你回来访问内存。但是应该注意的是,O/S 不保证I/O 将按照调用 madvise 的顺序完成。因此,O/S 可能会处理第一个 madvise,然后跳转到 madvise 的末尾,或者地址最低的那个,基本上任何它喜欢的。根本没有办法显着加快 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 更有意义。

于 2012-10-08T20:48:13.973 回答