Dask的并行for循环比单核慢

灯_B

我尝试过的

我有一个尴尬的并行for循环,其中我在两个嵌套的for循环中迭代90x360值并进行一些计算。我尝试dask.delayed按照本教程并行化for循环,尽管仅针对极少量的迭代进行了演示。

问题描述

我很惊讶地发现并行代码花费了2h 39分钟,而非并行定时花费1h 54分钟,这意味着我做的事情根本上是错误的,或者任务图太大而无法处理?

设置信息

该测试是针对我的部分迭代进行的,即10 x 360,但是优化的代码应该能够处理90 x 360的嵌套迭代。我的迷你集群具有66个核心和256 GB的RAM,两个数据文件分别为4 GB和<1 GB。对于此任务,我multi-processing对使用vs的方法也感到困惑multi-threading我认为在多个过程中运行类似于joblib默认实现的并行循环是每个循环在独立网格点上工作的方式。但是,表明这样multi-threading做速度更快,如果没有GIL问题(我没有),则应首选此方法。因此,对于上述时间,我使用了dask.delay默认调度选项,该选项对单个进程使用多线程选项。

简化代码

import numpy as np
import pandas as pd
import xarray as xr
from datetime import datetime
from dask import compute, delayed

def add_data_from_small_file(lat):
    """ for each grid-point, get time steps from big-file as per mask, and
        compute data from small file for those time-steps
        Returns: array per latitude which is to be stacked
    """

    for lon in range(0,360):
        # get time steps from big file
        start_time = big_file.time.values[mask1[:, la, lo]] 
        end_time = big_file.time.values[[mask2[:,la,lo]]

        i=0  
        for t1, t2 in zip(start_time, end_time):
              # calculate value from small file for each time pair
              temp_var[i] = small_file.sel(t=slice(t1, t2)).median()
              i=i+1

         temp_per_lon[:, lon] = temp_var
     return temp_per_lon



if __name__ == '__main__':
    t1 = datetime.now()
    small_file = xr.open_dataarray('small_file.nc') # size < 1 GB, 10000x91
    big_file = xr.open_dataset('big_file.nc') # size = 4 GB, 10000x91x360

    delayed_values = [delayed(add_data_from_small_file)(lat) for lat in range(0,10)] # 10 loops for testing, to scale to 90 loops
    # have to delay stacking to avoid memory error
    stack_arr = delayed(np.stack)(delayed_values, axis=1) 
    stack_arr = stack_arr.compute()
    print('Total run time:{}'.format(datetime.now()-t1))

麦考林

每个延迟的任务都会增加大约1毫秒的开销。因此,如果您的函数运行缓慢(也许您正在调用其他昂贵的函数),则可以选择dask.delayed为佳。如果没有,那么您可能应该寻找其他地方。

如果您对线程或进程是否对您更好感到好奇,那么找出最简单的方法就是尝试两者。这很容易做到。

dask.compute(*values, scheduler="processes")
dask.compute(*values, scheduler="threads")

即使您使用的是numpy数组,也有可能大部分时间实际上都花在了Python的循环上。如果是这样,多线程在这里无济于事,真正的解决方案是停止使用Python进行循环,要么通过精通numpy / xarray,要么使用类似Numba的项目。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在单核处理器上使用并行流会比使用顺序流慢吗?

来自分类Dev

并行比慢于

来自分类Dev

简单的OpenMP并行,循环速度比串行计算慢

来自分类Dev

简单的OpenMP并行,循环速度比串行计算慢

来自分类Dev

并行处理比顺序慢?

来自分类Dev

while循环性能单核与多核机器

来自分类Dev

并行化Dask聚合

来自分类Dev

单核cpu上的C#并行和多线程

来自分类Dev

为什么C#任务并行库代码比普通的for循环慢?

来自分类Dev

并行循环

来自分类Dev

并行For与For循环

来自分类Dev

当迭代次数足够高时,Dask 多处理失败,循环并行,包括调用 MongoDB

来自分类Dev

并行排序比串行排序慢

来自分类Dev

C ++ OpenMP并行比串行慢

来自分类Dev

C ++ OpenMP并行比串行慢

来自分类Dev

Perl中的慢循环

来自分类Dev

Mongodb慢更新循环

来自分类Dev

R中循环慢

来自分类Dev

超慢C ++ For循环

来自分类Dev

使用GCD的慢循环

来自分类Dev

R中循环慢

来自分类Dev

为什么Ubuntu在Atom双核上比Atom单核上慢?

来自分类Dev

多个进程是否可以在多线程单核 CPU 上并行运行?

来自分类Dev

dask.array.reshape非常慢

来自分类Dev

Joblib并行多个CPU比单个慢

来自分类Dev

并行实现比Julia中的串行实现慢

来自分类Dev

Joblib 简单示例并行示例比简单慢

来自分类Dev

不同DbContext的并行执行比非并行版本慢

来自分类Dev

数组遍历:并行性能比非并行慢