繁体   English   中英

对于 skimage,joblib.Parallel() 比 single 慢

[英]joblib.Parallel() slower than single for skimage

我必须为一堆图像的每个切片应用 2D 过滤器,并且我想并行化分析。 但是,下面的代码运行速度比正常的 for 循环慢。 此外,增加n_jobs也会增加处理时间,对于n_jobs = 1更快,对于n_jobs = 6更慢。

import numpy as np 
from joblib import Parallel, delayed
from skimage.restoration import denoise_tv_chambolle

arr = np.random.rand(50,50,50)

def f(arr):
    arr_h = denoise_tv_chambolle(arr, weight=0.1, multichannel=True)
    return arr_h

Parallel(n_jobs=6, backend="threading")(delayed(f)(i) for i in arr)

:(为什么)...运行速度比正常的 for 循环慢(?)

>>> import numpy as np; _ = np.random.rand( 50, 50, 50)
>>> from zmq import Stopwatch; aClk = Stopwatch()
>>> 
>>> aClk.start(); r = denoise_tv_chambolle( _, weight = 0.1, multichannel = True ); b = aClk.stop(); print( "The code took {0: > 9d}[us]".format( b ) )
The code took    679749[us]
The code took    683137[us]
The code took    678925[us]
The code took    688936[us]

鉴于float64的微型数据形状(50,50,50) ,缓存内计算是性能的关键。 使用带有“ threading ”后端的joblib.Parallel是相当反模式( python 使用GIL -lock 以便重新[SERIAL] -ise一步一步地计算,因为它避免了任何常见的,并发相关,冲突)。 这样的串行计算流程在这里更糟糕,因为“切换”一个接一个地需要额外的成本(不改进原始的纯 - [SERIAL]代码执行 - 所以你需要付出更多才能获得相同的结果(然而,经过更长的时间))

Q :增加n_jobs也会增加处理时间

当然,它增加了 GIL 锁定重新[SERIAL]化开销所浪费的时间量,因为有更多one-step-after-another GIL 导向的冲突避免“切换”转换。


最后但并非最不重要的

即使进入完全成熟的并行性,使用基于进程的并行性(避免 GIL 锁定的成本),它也会出现(再次以成本 - 进程实例化成本(python 的完整 1:1 内存副本) Win O/S 中的解释器进程n_jobs ,类似在 linux O/S 中 - 如joblib模块中所述,包括避免产生并行进程的其他一些 forms 的建议),参数 data-transfer-cost,result-transfer-cost )。

如果为n_jobs = 6添加所有这些附加成本,并且如果这些成本只是以一个微型计算任务的名义产生的(持续时间小至~ 680 [ms] ),那么很快就会导致支付设置并行处理的方式比以往任何时候都多(因为其他效果 - 作为比原始缓存重用更糟糕的方式 - 不会“提高”计算速度)。

计算有效载荷实际成本以及对每一类(所有此类)成本的适当考虑)是原因(为什么)......运行速度较慢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM