繁体   English   中英

为什么dask中的点积比numpy慢

[英]why is dot product in dask slower than in numpy

dask中的点积似乎比numpy慢得多:

import numpy as np
x_np = np.random.normal(10, 0.1, size=(1000,100))
y_np = x_np.transpose()
%timeit x_np.dot(y_np)
# 100 loops, best of 3: 7.17 ms per loop

import dask.array as da
x_dask = da.random.normal(10, 0.1, size=(1000,100), chunks=(5,5))
y_dask = x_dask.transpose()
%timeit x_dask.dot(y_dask)
# 1 loops, best of 3: 6.56 s per loop

有谁知道这可能是什么原因? 这里有什么我想念的吗?

调整块大小

@isternberg的答案是正确的,您应该调整块大小。 块大小的良好选择遵循以下规则

  1. 块应该小到足以舒适地放在记忆中。
  2. 一个块必须足够大,以便该块上的计算所花费的成本远远超过dask所产生的每个任务的1ms开销(因此100ms-1s是一个很好的数字来进行射击)。
  3. 块应该与您想要执行的计算一致。 例如,如果您计划经常沿特定维度切片,那么如果您的块已对齐以便您必须触摸更少的块,则效率会更高。

我通常拍摄大小为1-100兆字节的块。 任何小于此的东西都没有用,通常会产生足够的任务,调度开销成为我们最大的瓶颈。

关于原始问题的评论

如果你的数组只有大小(1000, 100) dask.array (1000, 100)那么就没有理由使用dask.array 相反,使用numpy,如果您真的关心使用多核,请确保您的numpy库与MLK或OpenBLAS等高效的BLAS实现相关联。

如果您使用多线程BLAS实现,您可能实际上想要关闭dask线程。 这两个系统会互相破坏并降低性能。 如果是这种情况,则可以使用以下命令关闭dask线程。

dask.set_options(get=dask.async.get_sync)

要实际执行dask.array计算,你必须在计算结束时添加一个.compute()调用,否则你只需要计算创建任务图所需的时间,而不是执行它。

更大的例子

In [1]: import dask.array as da

In [2]: x = da.random.normal(10, 0.1, size=(2000, 100000), chunks=(1000, 1000))  # larger example

In [3]: %time z = x.dot(x.T)  # create task graph
CPU times: user 12 ms, sys: 3.57 ms, total: 15.6 ms
Wall time: 15.3 ms

In [4]: %time _ = z.compute()  # actually do work
CPU times: user 2min 41s, sys: 841 ms, total: 2min 42s
Wall time: 21 s

在调整块时,dask中点积的计算运行得更快:

import dask.array as da
x_dask = da.random.normal(10, 0.1, size=(1000,100), chunks=1000)
y_dask = x_dask.transpose()
%timeit x_dask.dot(y_dask)
# 1000 loops, best of 3: 330 µs per loop

更多关于dask 文档中的块。

编辑:正如@MRocklin所写,要真正获得计算时间,必须在函数上调用.compute()

暂无
暂无

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

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