python - joblib.Parallel() 比 skimage 的 single 慢

标签 python parallel-processing cpu joblib parallelism-amdahl

我必须对图像堆栈的每个切片应用 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)

最佳答案

Q : ( Why ) ... runs slower than a normal for loop ( ? )

>>> 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]

考虑到微型数据形状 (50,50,50) -of- float64 ,缓存内计算是性能的关键。将 joblib.Parallel 与“ threading ”后端一起使用是相当反模式的(python 使用 GIL -lock 以便重新 [SERIAL] -ise 计算一步接一步,因为它避免了任何类型的常见的、与并发相关的冲突)。这种串行计算流在这里甚至更糟,因为“切换”一步接一个会产生额外的成本(而不是纯粹改进原始的- [SERIAL]代码执行 - 因此您需要付出更多才能获得相同的结果(但是,在更长的时间之后))

Q : increasing n_jobs also increase the processing time

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

<小时/>

最后但并非最不重要的

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

如果将 n_jobs = 6 的所有这些附加成本相加,并且这些成本只是以小型计算任务的名义累积的(小至 ~ 680 [ms] ) > 在持续时间内),很快就会导致支付更多来设置并行处理比收到的返回(作为其他效果 - 作为比原始缓存更糟糕的结果) -重用-不会“提高”计算速度)。

real-world costs ( and a due accounting for each class-of-(all-such)-costs ) of computing payloads 是原因 (为什么)... 运行速度较慢

关于python - joblib.Parallel() 比 skimage 的 single 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58698601/

相关文章:

docker - 制作一个 Dockerfile 来编译 Tensorflow 二进制文件以使用 : SSE4. 1、SSE4.2 和 AVX 指令

python - 数据框 - 对一些列求和,从其他列中获取最后一个值

python - 在 vi 编辑器中运行 python 代码并传递用户输入

python - 计算行数并根据字符串 [with str.contains] 在 python 中的位置创建标签列

python - Travis CI 故障排除指南

c++ - 如何在 std::reduce 和 std::accumulate 之间进行选择?

c# - .net Core Parallel.ForEach 问题

c++ - openCL平台/设备查询

cpu - PAPI:时钟引用周期是什么意思?

java - 如何让Java进程使用多个CPU核心