GIL锁会大大降低以下代码的性能吗?
每个块上的函数使用python循环而不是numpy函数。由于外部库,我必须使用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数组的其他操作。
从Wiki中,我看到了设置计算调度程序而不是函数的方法:
# 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()
python用于循环不会释放gil,因此很难与线程平行。在这种情况下,您有一些选项
- 使用Numba或Cython之类的项目编写发布GIL 的循环代码
使用将计算分配到多个过程的调度程序。我个人的建议是在本地使用Dask.Dask.Distribed Scheduler,这可以通过运行以下两行来完成:
from dask.distributed import Client client = Client()
但是,一如既往,您应该介绍您的代码并尝试一些事情。上面给出的建议取决于许多因素。例如,如果循环释放GIL。