【问题标题】:Is strided numpy array shared across multiple processes?跨多个进程是否共享 numpy 数组?
【发布时间】:2021-05-04 12:31:21
【问题描述】:

假设我们使用 stride 技巧创建了一个 numpy 数组,其中包含另一个数组的视图:

import numpy as np
from numpy.lib import stride_tricks
x = np.arange(20).reshape([4, 5])
arr = stride_tricks.as_strided(x, shape=(3, 2, 5),strides=(20, 20, 4))

我们可以确认这个新数组确实是一个视图:

assert not arr.flags['OWNDATA']
# True

问题:

如果我将arr 作为参数传递给multiprocessing.Process()arr 是否会被复制到每个进程中? x 会被复制吗?请解释原因。

【问题讨论】:

  • 我建议尝试一个小例子。我没有太多使用多处理,所以不能说视图会发生什么。虽然as_strided 视图不会增加内存使用,但使用它的许多操作会。我最近帮助了一位发帖人,他发现std 导致了内存错误,因为它从视图中减去了平均值。
  • 是的,每个参数都被腌制,然后在新进程中反序列化。 x 是否被复制取决于。
  • @juanpa.arrivillaga 你怎么能在不制作全新副本的情况下反序列化?
  • @MarkRansom 哦,参数总是被复制的。 x 是一个全局变量。这取决于如何/是否使用x 以及如何创建进程(例如 fork 与 spawn)

标签: python arrays numpy multiprocessing stride


【解决方案1】:

如果共享是通过pickle 序列化,那么显然view(如何生成)将产生一个副本:

In [298]: x = np.arange(10)
In [299]: y = x.reshape(2,5)
In [300]: import pickle
In [301]: B = pickle.dumps(y)
In [302]: Y = pickle.loads(B)
In [303]: Y
Out[303]: 
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
In [304]: y.__array_interface__['data']
Out[304]: (43176224, False)
In [305]: x.__array_interface__['data']
Out[305]: (43176224, False)
In [306]: Y.__array_interface__['data']
Out[306]: (59035584, False)

numpy 数组的 pickle 实际上是由 np.save 执行的。

通过x并在每个进程中制作视图可能会更好。

【讨论】:

  • "通过x 并在每个进程中制作视图可能会更好。" - 这不会避免复制。
猜你喜欢
  • 2013-04-05
  • 2021-09-23
  • 1970-01-01
  • 2021-05-31
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多