当循环迭代不是独立的时,使用OpenMP并行化循环

时间:2017-02-10 21:05:15

标签: c multithreading parallel-processing openmp

我有一个数字bessel过滤器的实现,这是我的程序的性能瓶颈。我想将主循环与OpenMP并行化。

该函数采用输入数组paddedsignal和滤波器系数数组dcofccof,并生成一个过滤的临时数组temp。这个过程的主循环如下所示:

    for (i=order; i<end; i++)
    {
        temp[i] = ccof[0]*paddedsignal[i];
        for (p=1; p<=order; p++)
        {
            temp[i] += ccof[p]*paddedsignal[i-p] - dcof[p]*temp[i-p];
        }
    }

请注意,temp[i]的值取决于temp[i-p]的先前值。这会混淆一个简单的#pragma omp for指令,因为temp[i]的值靠近数组的各个部分之间的边界,这些部分将由不同的线程处理,因此存在竞争条件问题。基本上,如果线程1取0到99之间的索引而线程2取100-199,那么100处的值将是错误的,因为它将在99之前的值之前计算,它取决于它。

有没有办法挽救这种情况?由于过滤值依赖于相邻值这一事实使得它本身就是一个连续计算,所以我对于我可以做什么来平行化这是绝望的。有没有办法解决这个问题?

2 个答案:

答案 0 :(得分:1)

由于您正确识别的依赖关系,您基本上无法并行化外部循环。

您可以通过缩小来并行化内循环。但这只会对大型signal有所帮助,甚至可能只是导致错误共享,因为数据是混乱的。有人可能会认为复杂的数据是在线程之间交错temp和{{1}},这需要排序手动工作共享结构。无论如何,我怀疑它是值得的,因为减少会增加管理成本。

如果可以替代具有有限脉冲响应的滤波器,则更容易并行化。您还可以将整个信号分割成稍微重叠的片段并独立计算滤波器,但这些块的边界会有一些计算错误。

答案 1 :(得分:0)

也许您正在为订购寻找#pragma omp。它按照顺序执行的顺序执行代码

但请记住:

  • 只能在for指令的动态范围内使用
  • 非常“昂贵”(你的加速可能不会像你想象的那么好)。

有关更多信息,请参阅: omp ordered