2017-12-23 5 views
0

GILロックは次のコードのパフォーマンスを大幅に低下させますか?dask.arrayとgilロック内のループ

各ブロックの関数は、numpy関数の代わりにpythonループを使用します。私は外部ライブラリのためにPythonループを使用する必要があります。

テストコード:

import numpy as np 
import dask.array as da 
import dask.sharedict as sharedict 
from itertools import product 


def block_func(block): 
    for i in range(len(block)): # <--- the python loop ... 
     block[i] += 1 
    return block 


def darr_func(x, name='test'): 
    dsk = {} 
    for idx in product(*map(range, x.numblocks)): 
     dsk[(name,) + idx] = (block_func, (x.name,) + idx) 
    dsk2 = sharedict.merge((name, dsk), x.dask) 
    return da.Array(dsk2, name, x.chunks, x.dtype) 


def main(): 
    n = 1000 
    chunks = 100 
    arr = np.arange(n*n).reshape(n, n) 
    darr = da.from_array(arr, chunks=chunks) 
    result = darr_func(darr) 
    print(result.compute()) 


main() 

その場合は、スケジューラのヘルプのためのコンテキストを設定することができますか? dask配列を使って関数のコンテキストを設定する方法は?私は、dask配列よりも他の操作にデフォルトのdaskスケジューラーを使いたい。

ウィキから、私が代わりに機能のコンピューティングのためのスケジューラを設定する方法を参照してください。

# As a context manager 
>>> with dask.set_options(get=dask.multiprocessing.get): 
...  x.sum().compute() 

# Set globally 
>>> dask.set_options(get=dask.multiprocessing.get) 
>>> x.sum().compute() 

答えて

1

PythonのforループGILを解放し、そのスレッドを並列化するのは難しいですしないでください。この場合、あなたは、いくつかのオプション

  1. はGIL
  2. は、複数のプロセスに出計算を分割スケジューラを使用して放出するためのループのコードを記述するNumbaまたはCythonのようなプロジェクトを使用しています。しかし、いつものようにあなたのコードをプロファイリングし、いくつかのことを試してみてください

    from dask.distributed import Client 
    client = Client() 
    

:私の個人的な勧告は以下の2行を実行することによって行うことができ、ローカルdask.distributedスケジューラを使用することです。上記のアドバイスは、多くの要因に依存します。例えば、ループの本体がGILを解放する場合、Python forループは問題にならないかもしれません。

関連する問題