【问题标题】:Writing into a NumPy memmap still loads into RAM memory写入 NumPy memmap 仍会加载到 RAM 内存中
【发布时间】:2014-01-09 20:57:09
【问题描述】:

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

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

如您所见,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

这些操作不知何故很快耗尽了我的 RAM。我认为 mem-mapping 基本上是核心外的numpy.ndarray。我弄错了吗?为什么我的内存使用量疯狂飙升?

【问题讨论】:

  • 如果内存可用,您为什么希望它不使用内存?那样会慢几个数量级,如果你没有将内存用于其他任何事情,那么你不会从这个成本中获得任何好处。在极少数情况下,您对内存需求的了解比操作系统猜测的多(例如,您有一大块很久没碰过的东西,但即将连续扫描 N 次),您可能需要手动 madvise/mprotect 或 Win32 等效项,否则,您根本不必担心。快速耗尽内存是正确的做法,所以要开心。
  • 看看pytables,这里可能是个好工具
  • 我认为 PyTables 不支持点积,这就是我研究 memmap 的原因。
  • pytables 不支持计算具有快速便利功能的巨大矩阵的点积。但是手动实现点积算法应该是相当简单的。
  • @richizy:mmap 数组非常稀疏的点积可能比scipy.sparse.cs{c,r}_matrix 慢几个数量级。密集矩阵乘法不会先验地知道零点在哪里,并且会遍历所有元素。

标签: python python-2.7 numpy


【解决方案1】:

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

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

【讨论】:

  • 所以memmap基本没用。
  • @agemO,我们的目标不是尽量减少 RAM 的使用。它适用于大于 ram 的 .npy 文件,或者您只需要访问几个元素而无需从磁盘加载整个文件的大文件。
  • '目标不是最小化 RAM 使用率' -> 然后我认为:'内存映射文件用于访问磁盘上大文件的小段,而不会将整个文件读入内存。 '真的是误导。这正是你可以阅读的关于 h5py 或一些 pandas 加载功能的句子,但在这些情况下,它的真正意思是“让我们逐块读取整个文件!”
【解决方案2】:

作为the docs say:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-14
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 2021-05-13
    • 2019-11-19
    相关资源
    最近更新 更多