チャンクサイズを調整する
チャンクサイズを調整する必要があるという@isternbergの回答は正しいです。チャンク サイズの適切な選択は、次の規則に従います。
- チャンクは、メモリに快適に収まる程度に小さくする必要があります。
- チャンクは、そのチャンクでの計算が、タスクごとに発生する 1 ミリ秒のオーバーヘッドよりも大幅に多くかかるように、十分な大きさでなければなりません (したがって、100 ミリ秒-1 秒は適切な数値です)。
- チャンクは、実行する計算に合わせて調整する必要があります。たとえば、特定の次元に沿って頻繁にスライスすることを計画している場合、チャンクが整列されていると、より少ないチャンクに触れる必要があり、より効率的です。
私は通常、1 ~ 100 メガバイトの大きさのチャンクを撮影します。それよりも小さいものは役に立たず、通常、スケジューリングのオーバーヘッドが最大のボトルネックになる十分なタスクが作成されます。
元の質問に関するコメント
配列のサイズのみの場合、(1000, 100)
使用する理由はありませんdask.array
。代わりに numpy を使用し、複数のコアの使用を本当に気にする場合は、numpy ライブラリが MLK や OpenBLAS などの効率的な BLAS 実装に対してリンクされていることを確認してください。
マルチスレッドの BLAS 実装を使用している場合、実際にはダッシュスレッドをオフにしたい場合があります。2 つのシステムが互いに干渉し合い、パフォーマンスが低下します。この場合は、次のコマンドを使用して、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