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
有人知道可能是什么原因吗?我在这里找不到任何东西?
答案 0 :(得分:5)
@isternberg的答案是正确的,你应该调整块大小。块大小的良好选择遵循以下规则
我通常会拍摄大小为1-100兆字节的块。任何小于此的东西都没有帮助,通常会产生足够的任务,调度开销成为我们最大的瓶颈。
如果您的数组只有(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
答案 1 :(得分:0)
调整块时,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 docs中的块。
修改强>
正如@MRocklin所写,要真正获得计算时间,必须在函数上调用.compute()
。