【发布时间】:2021-10-23 19:38:07
【问题描述】:
我无法在 python 中获得多处理的好处。基本上,计算时间会随着每个额外添加的核心而增加。所以我的猜测是这是由于开销,但我不确定我到底做错了什么以及如何改进/克服它。我真正的问题有点复杂,但我准备了一个更简单的例子来阐明我的问题。
简要说明:
我有一个相互独立的对象列表。对于每个对象,我需要调用一个函数,该函数将其他对象的字典作为输入。然后它对初始列表中的每个对象进行多次评估。所以它基本上是一个循环中的一个循环。
下面是一个非常简化版本的问题的代码
import time
import multiprocessing as mp
import numpy as np
def test_fun(iter_nr, mp_dict, i, return_dict):
dumm = 0
for j in range(iter_nr):
for val in mp_dict.values():
dumm += val
return_dict[i] = dumm
manager = mp.Manager()
return_dict = manager.dict()
mp_dict = manager.dict()
for i in range(100):
mp_dict[str(i)] = 1
nproc = [2,4,6,8,10,12,16,20]
nr_iter = 2*4*6*8*10
jobs = []
print('Total number of iterations: ', nr_iter)
if __name__ == '__main__':
for n_proc in nproc:
nr_iter_array = (nr_iter / n_proc ) * np.ones(n_proc)
print('Nr CPUs: ', n_proc)
print('Nr iterations per process: ', int(nr_iter_array[0]))
start_time = time.time()
for i in range(n_proc):
p = mp.Process(target = test_fun, args = (int(nr_iter_array[i]), mp_dict, i, return_dict))
p.start()
jobs += [p]
for job in jobs:
job.join()
end_time = time.time()
print(round(end_time - start_time, 3), 'sec')
这是输出
Total number of iterations: 3840
Nr CPUs: 2
Nr iterations per process: 1920
0.661 sec
Nr CPUs: 4
Nr iterations per process: 960
1.385 sec
Nr CPUs: 6
Nr iterations per process: 640
1.674 sec
Nr CPUs: 8
Nr iterations per process: 480
1.524 sec
Nr CPUs: 10
Nr iterations per process: 384
1.992 sec
Nr CPUs: 12
Nr iterations per process: 320
2.072 sec
Nr CPUs: 16
Nr iterations per process: 240
2.186 sec
Nr CPUs: 20
Nr iterations per process: 192
2.607 sec
如您所见,计算时间随着内核数量的增加而增加。这不是我所期望的。有谁知道这里发生了什么以及如何克服这个问题?
【问题讨论】:
-
工作负载越小,进程数越多,开销就越大。作为一般建议,确保工作线程有一些工作要做(>100 毫秒,越多越好),并且生成的进程不超过操作系统可用 CPU 数量的 2 倍。
-
CPU 的数量在这里不是问题。有 24 个可用。每个工人的工作也不应该成为问题,我需要为列表中的每个对象运行的计算非常繁重。
-
你的环境是什么?这可能是这里起作用的因素之一。 Linux?苹果?窗户?
-
环境是Linux。
标签: python python-multiprocessing shared-memory overhead