0

在我用 fortran 编写的顺序代码中,我有一个子程序来打乱一些以这种方式工作的向量:

    DO i=1,nsim

      IF(iflag(i) == 0)THEN

        j=j+1
        pos(j)=pos(i)
        v(j)=v(i)
        iflag(j)=iflag(i)

      END IF

    END DO
    nsim=j

我是新手 OpenMP 用户,所以我不知道如何以正确的方式编写此循环。最初,我认为是这样的:

!$omp parallel do reduction(+: j)
  DO i=1,nsim

  IF(iflag(i) == 0)THEN

    j=j+1
    pos(j)=pos(i)
    v(j)=v(i)
    iflag(j)=iflag(i)

  END IF

END DO
!$omp end parallel do
nsim=j

但我不知道是否可以通过这种方式产生竞争条件。关于如何更好地编写此循环的任何建议?提前致谢

4

1 回答 1

1

可以通过以下方式并行化这种循环:

  1. 在 1 和 0 的序列上使用“前缀和”运算,如果采用 THEN,则序列元素为 1,否则为 0。前缀和的结果告诉您每次迭代的 j 值。
  2. 使用步骤 1 中的 j 值执行 THEN 操作,将左侧替换为临时数组。
  3. 将临时数组复制回原始数组。

有关实现“前缀和”的详细信息,请参阅并行前缀和的讨论。步骤 2 可以嵌入到前缀和的“向下扫描”阶段(参见其他讨论)。因为前缀和使带宽消耗加倍(因为它是一个两遍算法),所以很难从中获得加速。

于 2013-06-20T20:21:01.513 回答