这种速度对于多处理星图来说是正常的吗



代码:

from multiprocessing import Pool
from itertools import repeat
import timeit
import multiprocessing
def add_one(number, flag):
new_number = None
if flag=="a":
new_number = number+1
return (number, new_number)
numbers = list(range(10000000))
pool = Pool(multiprocessing.cpu_count())
for i in range(3):
print(i)
start_time = timeit.default_timer()
flag = "a"
new_numbers = pool.starmap(add_one, zip(numbers, repeat(flag)))
print('time taken: ', timeit.default_timer() - start_time)

池计数配置分别为3、1和multiprocessing.cpu_count()。它们所花费的时间如下:

(base) ins-MacBook-Pro-2 graph_test % python test.py
0
time taken:  7.543301321
1
time taken:  7.8004514
2
time taken:  7.892797112
ins-MacBook-Pro-2 graph_test % python test.py
0
time taken:  11.030308790000001
1
time taken:  11.616422934
2
time taken:  11.846459496999998
ins-MacBook-Pro-2 graph_test % python test.py
0
time taken:  6.376773281
1
time taken:  6.876658618999999
2
time taken:  6.518348029

我的Mac有8个核心。它似乎没有加快多少速度。我使用星图的方式正确吗?

multiprocessing不会为细粒度并行度带来显著的加速——您需要;大(ger)工作;因为它在墙上的时钟时间里得到了回报。

调用add_one()函数所做的工作与使用多处理的开销相比简直微不足道。主程序必须隐藏参数,通过进程间通信机制发送这些字符串;然后工人必须解开这些争论;然后该函数做少量的工作,将字符串与"a"进行比较,并可能将1添加到整数,然后构建结果的2元组;然后,多处理机制不得不再次掩盖这一2元组;通过进程间通信机制将pickle发送回主程序;然后主程序必须取消拾取结果字符串,并将生成的2元组附加到列表中。

你"参见";支持这一切的工作很少,但总的来说,支持工作的成本远高于add_one()的调用。

为了使加速速度与使用的内核数量更加一致,add_one()需要花费更多的时间,因此有更多的潜力并行工作。例如,change:

if flag=="a":

if (flag * 100000)[0] =="a":

不,这不是一个明智的改变。这只是一种让add_one()消耗更多时间的方法,这样您就可以看到添加内核确实有帮助。它根本不会改变的开销,只是增加了在多处理实现的之外需要完成的工作量。让所有这些都变得无用"大字符串";可以而且将要并行进行。

注意:不要弄错"核心";对于";物理CPU";。CCD_ 7通常返回"0"的数目;逻辑";(非物理)核心。对于多处理,物理核心的数量通常要重要得多。

最新更新