我试图了解多处理如何与Python一起使用。这是我的测试代码:
import numpy as np
import multiprocessing
import time
def worker(a):
for i in range(len(a)):
for j in arr2:
a[i] = a[i]*j
return len(a)
arr2 = np.random.rand(10000).tolist()
if __name__ == '__main__':
multiprocessing.freeze_support()
cores = multiprocessing.cpu_count()
arr1 = np.random.rand(1000000).tolist()
tmp = time.time()
pool = multiprocessing.Pool(processes=cores)
result = pool.map(worker, [arr1], chunksize=1000000/(cores-1))
print "mp time", time.time()-tmp
我有8个核心。通常,它仅使用约3%的CPU进行7个过程,大约一秒钟,最后一个过程使用了CPU的〜1/8。>
我知道,分解通信通常会限制并行编程的复杂性,但是通常需要这么长时间?还有什么可能导致最后一个过程永远发生?
此线程:Python多处理从未加入似乎可以解决一个类似的问题,但是它不能解决池的问题。
看起来您想将工作分为块。您可以使用范围函数来分区数据。在Linux上,分叉的进程获得了父存储器的复制视图,因此您只需传递要处理的索引即可。在窗户上,没有这样的运气。您需要传递每个冠军。这个程序应该做
import numpy as np
import multiprocessing
import time
import platform
def worker(a):
if platform.system() == "Linux":
# on linux we passed in start:len
start, length = a
a = arr1[start:length]
for i in range(len(a)):
for j in arr2:
a[i] = a[i]*j
return len(a)
arr2 = np.random.rand(10000).tolist()
if __name__ == '__main__':
multiprocessing.freeze_support()
cores = multiprocessing.cpu_count()
arr1 = np.random.rand(1000000).tolist()
tmp = time.time()
pool = multiprocessing.Pool(processes=cores)
chunk = (len(arr1)+cores-1)//cores
# on Windows, pass the sublist, on linux just the indexes and let the
# worker split from the view of parent memory space
if platform.system() == "Linux":
seq = [(i, i+chunk) for i in range(0, len(arr1), chunk)]
else:
seq = [arr1[i:i+chunk] for i in range(0, len(arr1), chunk)]
result = pool.map(worker, seq, chunksize=1)
print "mp time", time.time()-tmp
您的意思是这里:
pool.map
将自动迭代程序中的[arr1]
对象。请注意,该对象是[arr1]
而不是arr1
,这意味着您传递给pool.map
的对象的长度仅为一个。
我认为最简单的解决方案是将[arr1]
替换为arr1
。