如何使用多处理来管理范围

问题描述 投票:0回答:1

我正在尝试实现一个使用python multiprocessing的函数,以加快计算速度。我正在尝试创建成对距离矩阵,但使用for循环的实现需要超过8小时。

这段代码似乎运行得更快,但是当我打印时,矩阵中充满了零。当我在函数中打印行时,它似乎工作。我认为是一个范围问题,但我无法理解如何处理它。

import multiprocessing
import time
import numpy as np

def MultiProcessedFunc(i,x):
    for j in range(i,len(x)):
        time.sleep(0.08)
        M[i,j] = (x[i]+x[j])/2
    print(M[i,:]) # Check if the operation works
    print('')

processes = []

v = [x+1 for x in range(8000)]
M = np.zeros((len(v),len(v)))

for i in range(len(v)):
    p = multiprocessing.Process(target = MultiProcessedFunc, args =(i,v))
    processes.append(p)
    p.start()

for process in processes:
    process.join()
end = time.time()

print('Multiprocessing: {}'.format(end-start))
print(M)

python python-multiprocessing multiprocess
1个回答
2
投票

不幸的是,你的代码不会以这种方式编写。多处理产生单独的进程,这意味着内存空间是分开的!一个子流程所做的更改不会反映在其他流程或您的父流程中。

严格来说,这不是一个范围问题。范围是在单个解释器进程中定义的内容。

模块does provide means of sharing memory between processes,但这是有代价的(由于锁定问题等共享内存的速度较慢。

现在,numpy有一个很好的功能:it releases the GIL during computation。这意味着使用多个threading而不是multiprocessing应该会给你带来一些好处,对你的代码几乎没有其他的改变,只需用import multiprocessingimport threading替换multiprocessing.Processthreading.Thread。代码应该产生正确的结果。在我的机器上,删除它在8秒内运行的打印语句和sleep代码:

Multiprocessing: 7.48570203781
[[1.000e+00 1.000e+00 2.000e+00 ... 3.999e+03 4.000e+03 4.000e+03]
 [0.000e+00 2.000e+00 2.000e+00 ... 4.000e+03 4.000e+03 4.001e+03]
 [0.000e+00 0.000e+00 3.000e+00 ... 4.000e+03 4.001e+03 4.001e+03]
 ...
 [0.000e+00 0.000e+00 0.000e+00 ... 7.998e+03 7.998e+03 7.999e+03]
 [0.000e+00 0.000e+00 0.000e+00 ... 0.000e+00 7.999e+03 7.999e+03]
 [0.000e+00 0.000e+00 0.000e+00 ... 0.000e+00 0.000e+00 8.000e+03]]

另一种方法是让您的子流程返回结果,然后将结果合并到主流程中。

© www.soinside.com 2019 - 2024. All rights reserved.