Python 如何使用多处理管理作用域
我正在尝试实现一个使用pythonPython 如何使用多处理管理作用域,python,python-multiprocessing,multiprocess,Python,Python Multiprocessing,Multiprocess,我正在尝试实现一个使用python多处理的函数,以加快计算速度。我正在尝试创建一个成对的距离矩阵,但是for循环的实现需要8个多小时 这段代码似乎运行得更快,但当我打印时,矩阵中充满了零。当我打印函数中的行时,它似乎可以工作。我认为这是一个范围问题,但我不知道如何处理它 import multiprocessing import time import numpy as np def MultiProcessedFunc(i,x): for j in range(i,len(x)):
多处理
的函数,以加快计算速度。我正在尝试创建一个成对的距离矩阵,但是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)
不幸的是,您的代码无法以这种方式编写。多处理产生独立的进程,这意味着内存空间是独立的!一个子流程所做的更改不会反映在其他流程或父流程中 严格来说,这不是一个范围问题。作用域是在单个解释器进程中定义的 但这是有代价的(由于锁定等问题,共享内存的速度要慢得多) 现在,numpy有一个很好的特性:。这意味着使用multi而不是
多处理
应该会给您带来一些好处,只需对代码进行少量其他更改,就可以将导入多处理
替换为导入线程
,并将多处理.Process
转换为线程.线程
。代码uld生成正确的结果。在我的机器上,删除打印语句和sleep
代码在8秒内运行:
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]]
另一种方法是让子进程返回结果,然后将结果合并到主进程中。不幸的是,您的代码无法以这种方式编写。多进程产生独立的进程,这意味着内存空间是独立的!一个子进程所做的更改不会反映在另一个子进程中进程或父进程 严格地说,这不是范围问题。范围是在单个解释器进程中定义的 但这是有代价的(由于锁定等问题,共享内存的速度要慢得多) 现在,numpy有一个很好的特性:。这意味着使用multi而不是
多处理
应该会给您带来一些好处,只需对代码进行少量其他更改,就可以将导入多处理
替换为导入线程
,并将多处理.Process
转换为线程.线程
。代码uld生成正确的结果。在我的机器上,删除打印语句和sleep
代码在8秒内运行:
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]]
另一种方法是让您的子进程返回结果,然后将结果合并到主进程中。当然可以使用
多处理
中的共享内存数组,但这是将其重写为numpy
数组的典型情况(如您所示)@MikeMcKerns是的,多处理数组不提供向量运算,这意味着它会慢得多。问题是,在原始程序中,我没有一个带数字的列表,而是一个带字符串的列表,我不能使用numpy for itAlso睡眠部分模拟真实世界中发生的事情code@GiuseppeMinardi使用数字与字符串s几乎总是需要不同的方法。如果没有这些细节,我们无法给你比我写的更好的建议:如果你需要共享内存,你必须使用多处理api,另一种方法是使用多处理.Pool
方法返回结果并在之后合并它们。哪种方法更有效取决于n您将要做什么,您可能必须分析这两种解决方案,以确定哪一种更适合您的情况。当然可以使用多处理
中的共享内存阵列,但这是将其重写为numpy
阵列的经典案例(如您所示)@MikeMcKerns是的,多处理数组不提供向量运算,这意味着它会慢得多。问题是,在原始程序中,我没有一个带数字的列表,而是一个带字符串的列表,我不能使用numpy for itAlso睡眠部分模拟真实世界中发生的事情code@GiuseppeMinardi使用数字与字符串s几乎总是需要不同的方法。如果没有这些细节,我们无法给你比我写的更好的建议:如果你需要共享内存,你必须使用多处理api,另一种方法是使用多处理.Pool
方法返回结果并在之后合并它们。哪种方法更有效取决于n您将要做的是,您可能必须分析这两种解决方案,以确定哪一种更好。请注意,如果您所追求的只是一个成对的欧几里德距离,则代码速度会快得多。请注意,如果您所追求的只是一个成对的欧几里德距离,则代码速度会快得多。