Ziq*_*Liu 2 python numpy multiprocessing python-3.x python-multiprocessing
我不确定这个标题是否适合我的情况:我想分享 numpy array 的原因是它可能是我的情况的潜在解决方案之一,但如果您有其他解决方案也很好。
我的任务:我需要实现一个具有多重处理的迭代算法,而每个进程都需要有一份数据副本(该数据很大,并且是只读的,并且在迭代算法期间不会改变)。
我写了一些伪代码来证明我的想法:
import multiprocessing
def worker_func(data, args):
# do sth...
return res
def compute(data, process_num, niter):
data
result = []
args = init()
for iter in range(niter):
args_chunk = split_args(args, process_num)
pool = multiprocessing.Pool()
for i in range(process_num):
result.append(pool.apply_async(worker_func,(data, args_chunk[i])))
pool.close()
pool.join()
# aggregate result and update args
for res in result:
args = update_args(res.get())
if __name__ == "__main__":
compute(data, 4, 100)
Run Code Online (Sandbox Code Playgroud)
问题是在每次迭代中,我都必须将数据传递给子进程,这是非常耗时的。
我想出了两种可能的解决方案:
那么,有什么方法可以在进程之间共享只读 numpy 数组吗?或者,如果您很好地实现了解决方案 2,它也可以工作。
提前致谢。
如果您绝对必须使用 Python 多处理,那么您可以使用 Python 多处理以及Arrow 的 Plasma 对象存储将对象存储在共享内存中并从每个工作线程访问它。看这个例子,它使用 Pandas 数据框而不是 numpy 数组执行相同的操作。
如果您不是绝对需要使用 Python 多重处理,则可以使用Ray更轻松地完成此操作。Ray 的优点之一是它不仅可以开箱即用地处理数组,还可以处理包含数组的 Python 对象。
在底层,Ray 使用Apache Arrow(一种零拷贝数据布局)序列化 Python 对象,并将结果存储在Arrow 的 Plasma 对象存储中。这允许工作任务对对象具有只读访问权限,而无需创建自己的副本。您可以阅读有关其工作原理的更多信息。
这是运行示例的修改版本。
import numpy as np
import ray
ray.init()
@ray.remote
def worker_func(data, i):
# Do work. This function will have read-only access to
# the data array.
return 0
data = np.zeros(10**7)
# Store the large array in shared memory once so that it can be accessed
# by the worker tasks without creating copies.
data_id = ray.put(data)
# Run worker_func 10 times in parallel. This will not create any copies
# of the array. The tasks will run in separate processes.
result_ids = []
for i in range(10):
result_ids.append(worker_func.remote(data_id, i))
# Get the results.
results = ray.get(result_ids)
Run Code Online (Sandbox Code Playgroud)
请注意,如果我们省略该行data_id = ray.put(data)并调用worker_func.remote(data, i),则data每个函数调用都会将该数组存储在共享内存中一次,这将是低效的。通过第一次调用ray.put,我们可以将对象一次性存储在对象存储中。
| 归档时间: |
|
| 查看次数: |
1872 次 |
| 最近记录: |