写入NumPy memmap仍然会加载到RAM内存中

ric*_*izy 7 python numpy python-2.7

我正在通过IPython Notebook测试NumPy的memmap,代码如下

Ymap = np.memmap('Y.dat', dtype='float32', mode='w+', shape=(5e6, 4e4))
Run Code Online (Sandbox Code Playgroud)

如你所见,它Ymap的形状非常大.我试图Ymap像稀疏矩阵一样填满.我没有使用scipy.sparse矩阵,因为我最终需要用另一个密集矩阵对它进行点积,这绝对不适合内存.

无论如何,我正在执行一系列很长的索引操作:

Ymap = np.memmap('Y.dat', dtype='float32', mode='w+', shape=(5e6, 4e4))
with open("somefile.txt", 'rb') as somefile:
    for i in xrange(5e6):
        # Read a line
        line = somefile.readline()
        # For each token in the line, lookup its j value
        # Assign the value 1.0 to Ymap[i,j]
        for token in line.split():
            j = some_dictionary[token]
            Ymap[i,j] = 1.0
Run Code Online (Sandbox Code Playgroud)

这些操作不知何故很快耗尽了我的RAM.我认为mem-mapping基本上是一个核心内容numpy.ndarray.我错了吗?为什么我的记忆力如此疯狂?

Fre*_*Foo 14

(非匿名)mmap是文件和RAM之间的链接,大致可以保证当RAM mmap已满时,数据将被分页到给定文件而不是交换磁盘/文件,当你msyncmunmap它时, RAM的整个区域被写入文件.操作系统通常遵循惰性策略.磁盘访问(或急切的RAM):只要数据适合,数据就会保留在内存中.这意味着具有大型mmaps的进程将占用尽可能多的RAM,然后将其余部分溢出到磁盘.

所以你是对的,一个np.memmap数组是一个核外数组,但它是一个可以尽可能多地获取RAM缓存的数组.


Tim*_*ers 6

正如文档所说

内存映射文件用于访问磁盘上大文件的小段,而无需将整个文件读入内存。

计算机中没有真正的魔法;-) 如果您访问的巨大数组很少,那么 memmap 噱头将需要很少的 RAM;如果您访问大量庞大的数组,则 memmap 噱头将需要非常多的 RAM。

一种可能对您的特定代码有帮助也可能没有帮助的解决方法:在工作流程的逻辑点定期创建新的 mmap 对象(并删除旧的)。那么所需的 RAM 量应该与您在这些步骤之间接触的数组项的数量大致成正比。与此相反,创建和销毁新的 mmap 对象需要时间。所以这是一个平衡的行为。