为什么 joblib 并行执行会使运行时间变慢?

2023-11-29

我想在 3D 中打乱值numpy-array,但仅当它们 > 0 时。

当我使用单核运行函数时,它比使用 2 个核运行要快得多。这远远超出了创建新的 python 进程的开销。我缺少什么?

以下代码输出:

random shuffling of markers started
time in serial execution:                          1.0288s
time executing in parallel with num_cores=1:       0.9056s
time executing in parallel with num_cores=2:     273.5253s
import numpy as np
import time
from random import shuffle
from joblib import Parallel, delayed  
import multiprocessing

import numpy as np

def randomizeVoxels(V,markerLUT):
    V_rand=V.copy()
    # the xyz naming here does not match outer convention, which will depend on permutation
    for ix in range(V.shape[0]):
        for iy in range(V.shape[1]):
            if V[ix,iy]>0:
                V_rand[ix,iy]=markerLUT[V[ix,iy]]

    return V_rand

V_ori=np.arange(1000000,-1000000,-1).reshape(100,100,200)

V_rand=V_ori.copy()

listMarkers=np.unique(V_ori)
listMarkers=[val for val in listMarkers if val>0]

print("random shuffling of markers started\n")

reassignedMarkers=listMarkers.copy()
#random shuffling of original markers
shuffle(reassignedMarkers)

markerLUT={}
for i,iMark in enumerate(listMarkers):
    markerLUT[iMark]=reassignedMarkers[i]

tic=time.perf_counter()

for ix in range(len(V_ori)):
    for iy in range(len(V_ori[0])):
        for iz in range(len(V_ori[0][0])):
            if V_ori[ix,iy,iz]>0:
                V_rand[ix,iy,iz]=markerLUT[V_ori[ix,iy,iz]]

toc=time.perf_counter()

print("time in serial execution: \t\t\t{: >4.4f} s".format(toc-tic))

#######################################################################3

num_cores = 1

V_rand=V_ori.copy()

tic=time.perf_counter()

results= Parallel(n_jobs=num_cores)\
    (delayed(randomizeVoxels)\
        (V_ori[imSlice,:,:],
        markerLUT
        )for imSlice in range(V_ori.shape[0]))

for i,resTuple in enumerate(results):
    V_rand[i,:,:]=resTuple

toc=time.perf_counter() 

print("time executing in parallel with num_cores={}:\t{: >4.4f} s".format(num_cores,toc-tic))    

num_cores = 2

V_rand=V_ori.copy()

MASK = "time executing in parallel with num_cores={}:\t {: >4.4f}s"

tic=time.perf_counter() #----------------------------- [PERF-me]

results= Parallel(n_jobs=num_cores)\
    (delayed(randomizeVoxels)\
        (V_ori[imSlice,:,:],
        markerLUT
        )for imSlice in range(V_ori.shape[0]))

for i,resTuple in enumerate(results):
    V_rand[i,:,:]=resTuple

toc=time.perf_counter() #----------------------------- [PERF-me]

print( MASK.format(num_cores,toc-tic) )

Q : “我错过了什么?”

最有可能的是内存 I/O 瓶颈。

enter image description here

虽然numpy-这里处理的一部分似乎相当浅(shuffle 不计算一点,而是在一对位置之间移动数据,不是吗?),在大多数情况下,这不允许“时间足够” “(通过做任何有用的工作)以便让内存 I/O 被重新排序的 CPU 核心指令屏蔽(参考 1)。延迟成本用于当代超标量 CISC 架构最低级别的直接 + 跨 QPI 内存 I/O 操作,具有高度推测性分支预测(对于内存 I/O 绑定的非分支精心制作的部分没有用)和多核和多核 NUMA 设计)。

This is most probably why even the first spin-off concurrent process (no matter if enforced for camping on the same (here a shared-CPU-core time by an interleaving pair of a two-step dancing processes, again memory-I/O bound, with even worse chances for latency masking on shared memory-I/O channels...) or any other (here adding cross-QPI add-on latency costs if having to perform non-local memory-I/O, again worsening chances for memory-I/O latency-masking) CPU-core.

由 CPU 时钟升压策略的冲突效应强制执行的 CPU 核心跳跃(后来开始违反热管理,因此跳跃进程以驻扎在下一个较冷的 CPU 核心上)将使所有 CPU 核心缓存优势失效,由于下一个较冷的核心上没有预缓存的数据可用,因此必须再次重新获取所有(一旦预缓存到最快的 L1data 缓存中)数据(也许,对于内存占用较大的数组对象,甚至需要跨 QPI 获取),因此利用更多内核不会对最终效率产生微不足道的影响。

enter image description here

;o)
The numpy高性能和智能处理并不是应该受到指责的地方 - 恰恰相反 - 它显然揭开了 CPU 的面纱”饥饿“状态 - 多年来一直被认为是我们所有现代 CPU 的性能上限 - 这就是为什么我们看到如此多核心的 CPU,它们试图通过拥有越来越多的核心来规避这个瓶颈 - 请参阅引用的评论硅级分析多于。

最后但并非最不重要的
代码原样包含大量提高其性能的机会,numpy-smart-vectorized 是第一个命名的,避免range()-循环,所以有更多的技巧需要遵循,所有这些最终都会让你陷入同样的​​麻烦——CPU 饥饿上限

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 joblib 并行执行会使运行时间变慢? 的相关文章

  • pandas Wide_to_long 后缀参数

    我对在 pandas 中使用 Wide to long 时的参数有疑问 有一个参数叫suffix我不明白 在文档中它说 后缀 str 默认 d 捕获所需后缀的正则表达式 d 捕获数字后缀 没有数字的后缀可以用否定字符类 D 指定 您还可以进
  • Tipfy:如何在模板中显示blob?

    鉴于在 gae 上使用tipfy http www tipfy org python 以下模型 greeting avatar db Blob avatar 显示 blob 此处为图像 的模板标签是什么 在这种情况下 斑点是一个图像 这很棒
  • Paramiko SSHException 通道已关闭

    我一直在使用 Paramiko 在 Linux Windows 机器上发送命令 它可以很好地在 Ubuntu 机器上远程执行测试 但是 它不适用于 Windows 7 主机 以下是我收到的错误 def unit for event self
  • 如何使用 i18n 切换器将“LANGUAGE_CODE”保存到数据库,以便在 Django 中的不同浏览器中语言不会更改?

    有什么办法可以改变它的值LANGUAGE CODE单击按钮 发送请求 时 settings py 中的变量会动态变化吗 我希望用户设置自己的 默认语言 他们的帐户 现在 用户可以使用下拉列表选择他们的首选语言 并且网站会得到完美的翻译 并且
  • scikit-learn 和tensorflow 有什么区别?可以一起使用它们吗?

    对于这个问题我无法得到满意的答案 据我了解 TensorFlow是一个数值计算库 经常用于深度学习应用 而Scikit learn是一个通用机器学习框架 但它们之间的确切区别是什么 TensorFlow 的目的和功能是什么 我可以一起使用它
  • Django 模型字段默认基于另一个模型字段

    我使用 Django Admin 构建一个管理站点 有两张表 一张是ModelA其中有数据 另一个是ModelB里面什么也没有 如果一个模型字段b b in ModelB为None 可以显示在网页上 值为ModelA的场a b 我不知道该怎
  • 在谷歌云上训练神经网络时出现“无法获取路径的文件系统”错误

    我正在使用 Google Cloud 在云上训练神经网络 如下例所示 https cloud google com blog big data 2016 12 how to classify images with tensorflow u
  • Pandas:将 pytz.FixedOffset 应用于系列

    我有一个带有timestamp列看起来像这样 0 2020 01 26 05 00 00 08 00 1 2020 01 26 06 00 00 08 00 Name timestamp dtype datetime64 ns pytz F
  • 将列表中的 None 替换为最左边的非 none 值

    Given a None 1 2 3 None 4 None None I d like a None 1 2 3 3 4 4 4 目前我已经用以下方法强制它 def replaceNoneWithLeftmost val last Non
  • Jupyter Notebook 中的深色模式绘图 - Python

    我正在使用 Jupyter Notebook 目前正在使用 JupyterThemes 的深色日光主题 我注意到我的绘图不是处于黑暗模式 并且文本仍然是黑色并且在日光照射的背景上无法读取 JupyterThemes 的自述文件建议在 ipy
  • 线性同余生成器 - 如何选择种子和统计检验

    我需要做一个线性同余生成器 它将成功通过所选的统计测试 我的问题是 如何正确选择发电机的数字以及 我应该选择哪些统计检验 我想 均匀性的卡方频率测试 每代收集10 000个号码的方法 将 0 1 细分为10个相等的细分 柯尔莫哥洛夫 斯米尔
  • 根据列索引重命名 Dataframe 列

    是否有内置函数可以按索引重命名 pandas 数据框 我以为我知道列标题的名称 但事实证明第二列中有一些十六进制字符 根据我接收数据的方式 我将来可能会在第 2 列中遇到这个问题 因此我无法将这些特定的十六进制字符硬编码到 datafram
  • 在 scipy 中创建新的发行版

    我试图根据我拥有的一些数据创建一个分布 然后从该分布中随机抽取 这是我所拥有的 from scipy import stats import numpy def getDistribution data kernel stats gauss
  • 在 HDF5 (PyTables) 中存储 numpy 稀疏矩阵

    我在使用 PyTables 存储 numpy csr matrix 时遇到问题 我收到此错误 TypeError objects of type csr matrix are not supported in this context so
  • 如何更改matplotlib中双头注释的头大小?

    Below figure shows the plot of which arrow head is very small 我尝试了下面的代码 但它不起作用 它说 引发 AttributeError 未知属性 s k 属性错误 未知属性头宽
  • 在父类中访问子类变量

    我有一个父类和一个继承的子类 我想知道如何访问我的父类中的子类变量 我尝试了这个但失败了 class Parent object def init self print x class Child Parent x 1 x Child Er
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • 如何使用 Python 3 正确显示倒计时日期

    我正在尝试获取将显示的倒计时 基本上就像一个世界末日时钟哈哈 有人可以帮忙吗 import os import sys import time import datetime def timer endTime datetime datet
  • 使用 SERVER_NAME 时出现 Flask 404

    在我的 Flask 配置中 我将 SERVER NAME 设置为 app example com 之类的域 我这样做是因为我需要使用url for with external网址 如果未设置 SERVER NAME Flask 会认为服务器
  • 在python中对列表列表执行行总和和列总和

    我想用python计算矩阵的行和和列和 但是 由于信息安全要求 我无法使用任何外部库 因此 为了创建矩阵 我使用了列表列表 如下所示 matrix 0 for x in range 5 for y in range 5 for pos in

随机推荐