3 python parallel-processing parallelism-amdahl dask
为了更好地理解并行,我比较了一组不同的代码。
这是基本的(code_piece_1)。
import time
# setup
problem_size = 1e7
items = range(9)
# serial
def counter(num=0):
junk = 0
for i in range(int(problem_size)):
junk += 1
junk -= 1
return num
def sum_list(args):
print("sum_list fn:", args)
return sum(args)
start = time.time()
summed = sum_list([counter(i) for i in items])
print(summed)
print('for loop {}s'.format(time.time() - start))
Run Code Online (Sandbox Code Playgroud)
此代码以串行方式(for 循环)运行时间消耗者并得到此结果
sum_list fn: [0, 1, 2, 3, 4, 5, 6, 7, 8]
36
for loop 8.7735116481781s
Run Code Online (Sandbox Code Playgroud)
多处理风格是否可以被视为实现并行计算的一种方式?
我认为是的,因为医生是这么说的。
这是code_piece_2
import multiprocessing
start = time.time()
pool = multiprocessing.Pool(len(items))
num_to_sum = pool.map(counter, items)
print(sum_list(num_to_sum))
print('pool.map {}s'.format(time.time() - start))
Run Code Online (Sandbox Code Playgroud)
该代码以多处理方式运行同一时间的消费者并得到了这个结果
sum_list fn: [0, 1, 2, 3, 4, 5, 6, 7, 8]
36
pool.map 1.6011056900024414s
Run Code Online (Sandbox Code Playgroud)
显然,在这种特殊情况下,多处理比串行处理更快。
Dask是一个灵活的 Python 并行计算库。
这段代码(code_piece_3)与 Dask 运行相同的时间消费者(我不确定我是否以正确的方式使用 Dask。)
@delayed
def counter(num=0):
junk = 0
for i in range(int(problem_size)):
junk += 1
junk -= 1
return num
@delayed
def sum_list(args):
print("sum_list fn:", args)
return sum(args)
start = time.time()
summed = sum_list([counter(i) for i in items])
print(summed.compute())
print('dask delayed {}s'.format(time.time() - start))
Run Code Online (Sandbox Code Playgroud)
我有
sum_list fn: [0, 1, 2, 3, 4, 5, 6, 7, 8]
36
dask delayed 10.288054704666138s
Run Code Online (Sandbox Code Playgroud)
我的CPU有6个物理核心
为什么 Dask 执行速度如此之慢,而多处理执行速度却如此之快?
我使用 Dask 的方式是否错误?如果是,正确的方法是什么?
注:请结合本案例或其他具体案例进行讨论。请不要泛泛而谈。
在您的示例中,dask 比 python 多处理慢,因为您没有指定调度程序,因此 dask 使用默认的多线程后端。正如 mdurant 所指出的,您的代码不会释放 GIL,因此多线程无法并行执行任务图。
请查看此处,了解该主题的详细概述:https ://docs.dask.org/en/stable/scheduler-overview.html
对于您的代码,您可以通过调用以下命令切换到多处理后端:
.compute(scheduler='processes')。
如果使用多处理后端,进程之间的所有通信仍然需要通过主进程。因此,您可能还想查看分布式调度程序,其中工作进程可以直接相互通信,这对于复杂的任务图尤其有益。此外,分布式调度程序支持工作窃取以平衡进程之间的工作,并具有提供一些有关正在运行的任务的诊断信息的 Web 界面。即使您只想在本地计算机上进行计算,使用分布式调度程序而不是多处理调度程序通常更有意义。