调整块大小
@isternberg 的答案是正确的,您应该调整块大小。一个好的块大小选择遵循以下规则
- 一个块应该足够小以舒适地放入内存中。
- 一个块必须足够大,以便对该块的计算花费的开销远远超过 dask 产生的每个任务的 1ms 开销(因此 100ms-1s 是一个很好的数字)。
- 块应该与您想要执行的计算保持一致。例如,如果您计划经常沿特定维度进行切片,那么如果您的块对齐,这样您就必须接触更少的块,这样会更有效。
我通常会拍摄 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