比赛条件? -多线程结果不同于单线程

时间:2019-10-21 15:09:12

标签: python parallel-processing cython

我正在研究一种并行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值应相同。现在不是这种情况。

1 个答案:

答案 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

mpmpi的赋值会在从0到一定数量的偏移量范围内运行(我们不知道,因为这是一个不完整的示例,但是它不尤其重要)。 在每个线程中发生

由于您的算法似乎可以同时在循环中更新mp并在同一循环中使用mp,因此对我来说似乎并不是特别可并行化。 (也许可以并行化内部(offset)循环,但我认为这会导致...[offset + diag]行出现问题。)


本质上,如果将循环与索引diag并行化,则循环中唯一需要更改的内容是:

  1. 单个值作为“归约变量”(+-*/

  2. 仅用diagdiag索引的数组。

有时候可能会发生其他事情,但是您必须了解自己正在做的事情,并向自己证明了多个线程没有在写相同的数据。

相关问题