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



我正在尝试实现一个使用Python multiprocessing的函数,以加快计算。我正在尝试创建一个成对距离矩阵,但用于循环的实现需要超过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)

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

严格来说,这不是一个范围的问题。范围是单个解释器过程中定义的东西。

该模块确实提供了在过程之间共享内存的手段,但这是有代价的(由于锁定问题等,共享内存速度较慢。

现在,Numpy具有一个不错的功能:它在计算过程中释放GIL。这意味着,使用多threading代替multiprocessing应该给您一些好处,而对于代码的其他更改,只需将import multiprocessingimport threadingmultiprocessing.Process替换为threading.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]]

一种替代方法是让您的子过程 return 结果,然后将结果组合到主过程中。

最新更新