我正在研究一种并行Cython算法,该算法利用“ prange”函数进行并行化。基本上,我有一个并行更新的numpy内存视图。我已经注意到,由于值与单线程结果不同,因此存在竞争状况或某些情况。有人能给我什么指导吗?
我尝试调整“ prange”参数,但似乎无法解决问题。我对C的理解是相当有限的,但我确实读过它,以了解循环中的变量都是应有的私有变量。
mp和mpi是内存视图。
for diag in prange(minlag, profile_len, num_threads=n_jobs, nogil=True):
c = 0
for i in range(diag, diag + w):
c = c + ((ts[i] - mu[diag]) * (ts[i-diag] - mu[0]))
for offset in range(n - w - diag + 1):
c = c + df[offset] * dg[offset + diag] + df[offset + diag] * dg[offset]
c_cmp = c * sig[offset] * sig[offset + diag]
# update the distance profile and profile index
if c_cmp > mp[offset]:
if c_cmp > 1:
c_cmp = 1
mp[offset] = c_cmp
mpi[offset] = offset + diag
if c_cmp > mp[offset + diag]:
if c_cmp > 1:
c_cmp = 1
mp[offset + diag] = c_cmp
mpi[offset + diag] = offset
对于单线程和多线程,mp和mpi值应相同。现在不是这种情况。
答案 0 :(得分:0)
for offset in range(n - w - diag + 1):
# ... some stuff ...
mp[offset] = c_cmp
mpi[offset] = offset + diag
# ... some stuff ...
mp[offset + diag] = c_cmp
mpi[offset + diag] = offset
对mp
和mpi
的赋值会在从0
到一定数量的偏移量范围内运行(我们不知道,因为这是一个不完整的示例,但是它不尤其重要)。 在每个线程中发生。
由于您的算法似乎可以同时在循环中更新mp
并在同一循环中使用mp
,因此对我来说似乎并不是特别可并行化。 (也许可以并行化内部(offset
)循环,但我认为这会导致...[offset + diag]
行出现问题。)
本质上,如果将循环与索引diag
并行化,则循环中唯一需要更改的内容是:
单个值作为“归约变量”(+-*/
)
仅用diag
和diag
索引的数组。
有时候可能会发生其他事情,但是您必须了解自己正在做的事情,并向自己证明了多个线程没有在写相同的数据。