我正试图进入达斯克。为此,我试图并行化我得到的一些耗时的顺序代码。原始代码是这样的:
def sequential():
sims = []
chunksize = len(tokens)//4
for i in range(0, len(tokens), chunksize):
print(i, i+chunksize)
chunk = tokens[i:i+chunksize]
sims.append(process(chunk))
return sims
%time sequential()
和通用代码是这样的:
def parallel():
sims = []
chunksize = len(tokens)//4
for i in range(0, len(tokens), chunksize):
print(i, i+chunksize)
chunk = dask.delayed(tokens[i:i+chunksize])
sims.append(dask.delayed(process)(chunk))
return dask.delayed(sims)
%time parallel().visualize()
但是并行代码始终比并行代码慢10%。当我可视化sims
的计算图时,我得到了:
不确定list-#8
的来源,但看起来还是正确的。那么为什么没有加速呢?当我查看htop时,我看到3个核心处于活动状态(每个负载约30%),而对于顺序代码,我仅看到1个核心处于活动状态(负载100%)。顺序代码运行7分钟,而并行代码运行7-8分钟。
我想我误会了delayed
和compute
在这里应该使用吗?
如果需要,设置是这样的:
import numpy
import spacy
import dask
nlp = spacy.load('en_core_web_lg')
tokens = [t for t in nlp(" ".join(t.strip() for t in open('./words.txt','r').readlines())) if len(t.text) > 1 and len(t.text) < 20]
def process(chunk):
sims = numpy.zeros([len(chunk),len(tokens)], dtype=numpy.float32)
for i in range(len(chunk)):
for j in range(len(tokens)):
sims[i,j] = chunk[i].similarity(tokens[j])
return sims
答案 0 :(得分:2)
您正在看到此行为,因为dask的默认执行引擎基于单个进程中的多个线程(“线程”调度程序)。 Python具有一个锁GIL,该锁通过一次仅执行一个python语句来确保解释器的安全。因此,每个线程都在花费大部分时间等待锁变得可用。 为避免此问题,您有两种选择:
更多信息:http://dask.pydata.org/en/latest/scheduler-overview.html