我有一个数字bessel过滤器的实现,这是我的程序的性能瓶颈。我想将主循环与OpenMP并行化。
该函数采用输入数组paddedsignal
和滤波器系数数组dcof
和ccof
,并生成一个过滤的临时数组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之前的值之前计算,它取决于它。
有没有办法挽救这种情况?由于过滤值依赖于相邻值这一事实使得它本身就是一个连续计算,所以我对于我可以做什么来平行化这是绝望的。有没有办法解决这个问题?
答案 0 :(得分:1)
由于您正确识别的依赖关系,您基本上无法并行化外部循环。
您可以通过缩小来并行化内循环。但这只会对大型signal
有所帮助,甚至可能只是导致错误共享,因为数据是混乱的。有人可能会认为复杂的数据是在线程之间交错temp
和{{1}},这需要排序手动工作共享结构。无论如何,我怀疑它是值得的,因为减少会增加管理成本。
如果可以替代具有有限脉冲响应的滤波器,则更容易并行化。您还可以将整个信号分割成稍微重叠的片段并独立计算滤波器,但这些块的边界会有一些计算错误。
答案 1 :(得分:0)
也许您正在为订购寻找#pragma omp。它按照顺序执行的顺序执行代码
但请记住:
有关更多信息,请参阅: omp ordered