【问题标题】:Lock free read only List in Python?Python中的无锁只读列表?
【发布时间】:2011-06-12 14:48:47
【问题描述】:

我已经完成了一些基本的性能和内存消耗基准测试,我想知道是否有任何方法可以让事情变得更快......

  1. 我有一个包含 70,000 个元素的巨型列表,其中包含一个 numpy ndarray,以及该列表中元组中的文件路径。

  2. 我的第一个版本将列表的切片副本传递给 python 多进程模块中的每个进程,但它会使 ram 使用量激增至超过 20 GB

  3. 第二个版本我将它移动到全局空间并通过索引(例如 foo[i])在我的每个进程的循环中访问它,这似乎将它放入共享内存区域/CoW 语义中进程因此它不会爆炸内存使用量(保持在 ~3 GB)

  4. 但是,根据性能基准/跟踪,现在大部分应用程序时间似乎都花在“获取”模式...

所以我想知道是否有任何方法可以以某种方式将此列表转换为某种无锁/只读,以便我可以取消部分获取步骤以帮助加快访问速度。

编辑 1:这是应用分析的前几行输出

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   65 2450.903   37.706 2450.903   37.706 {built-in method acquire}
39320    0.481    0.000    0.481    0.000 {method 'read' of 'file' objects}
  600    0.298    0.000    0.298    0.000 {posix.waitpid}
   48    0.271    0.006    0.271    0.006 {posix.fork}

编辑 2:这是列表结构的示例:

# Sample code for a rough idea of how the list is constructed
sim = []
for root, dirs, files in os.walk(rootdir):
    path = os.path.join(root, filename)
    image= Image.open(path)
    np_array = np.asarray(image)
    sim.append( (np_array, path) )

# Roughly it would look something like say this below
sim = List( (np.array([[1, 2, 3], [4, 5, 6]], np.int32), "/foobar/com/what.something") )

那么今后 SIM 列表将是只读的。

【问题讨论】:

    标签: python performance numpy


    【解决方案1】:

    multiprocessing 模块提供了您所需要的:一个带有可选锁定的共享数组,即multiprocessing.Array 类。将lock=False 传递给构造函数以禁用锁定。

    编辑(考虑到您的更新):事情实际上比我最初预期的要复杂得多。列表中所有元素的数据都需要在共享内存中创建。是否将列表本身(即指向实际数据的指针)放在共享内存中并不重要,因为与所有文件的数据相比,这应该很小。要将文件数据存储在共享内存中,请使用

    shared_data = multiprocessing.sharedctypes.RawArray("c", data)
    

    其中data 是您从文件中读取的数据。要在其中一个进程中将其用作 NumPy 数组,请使用

    numpy.frombuffer(shared_data, dtype="c")
    

    这将为共享数据创建一个 NumPy 数组视图。同样,要将路径名放入共享内存,请使用

    shared_path = multiprocessing.sharedctypes.RawArray("c", path)
    

    其中 path 是一个普通的 Python 字符串。在您的进程中,您可以使用 shared_path.raw 将其作为 Python 字符串访问。现在将(shared_data, shared_path) 附加到您的列表中。该列表将被复制到其他进程,但实际数据不会。

    我最初打算使用multiprocessing.Array 作为实际列表。这是完全可能的,并且可以确保列表本身(即指向数据的指针)也在共享内存中。现在我认为这根本不是那么重要,只要实际数据是共享的。

    【讨论】:

    • 我的问题是我需要一些方法来存储一个 numpy ndarray + 文件路径。我对 Array 的理解是它只存储 1 个元素,例如说 'c' 它不能存储 "char"
    • @Pharaun:也许我没有正确理解您的列表结构。您能否在问题中更明确地说明这一点?我很确定 Array 类可以用于您的应用程序。
    • @Sven,我已经用一个粗略的示例更新了上面的问题,该示例是如何在 edit2 下构建列表的,因此应该给出一个想法......
    • @Pharaun:好的,我将编辑我的答案以使其更具体。
    • @Sven,嗯,从来没有想过那种方法,我需要做一些实验才能让它去完全理解它,但它看起来不错:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多