gpt4 book ai didi

c++ - OpenMP 并行代码与串行代码的输出不同

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:22:31 25 4
gpt4 key购买 nike

我不得不更改和扩展我的算法以进行一些信号分析(使用 polyfilterbank 技术)并且不能使用我的旧 OpenMP 代码,但是在新代码中结果并不像预期的那样(结果在开始位置与串行运行相比,该数组在某种程度上是不正确的 [串行代码显示预期结果])。

所以在第一个循环 tFFTin 中,我有一些 FFT 数据,我将其与窗口函数相乘。

目标是一个线程为每个多相因子运行内部循环。为了避免锁定,我使用了 reduction pragma(没有复杂的 reduction 是标准定义的,所以我使用我的那个,其中每个线程的 omp_priv 变量都用 omp_orig [所以用 tFFTin] 初始化)。我使用有序 pragma 的原因是结果应该以有序的方式添加到输出 vector 。

typedef std::complex<float> TComplexType;
typedef std::vector<TComplexType> TFFTContainer;

#pragma omp declare reduction(complexMul:TFFTContainer:\
transform(omp_in.begin(), omp_in.end(),\
omp_out.begin(), omp_out.begin(),\
std::multiplies<TComplexType>()))\
initializer (omp_priv(omp_orig))


void ConcreteResynthesis::ApplyPolyphase(TFFTContainer& tFFTin, TFFTContainer& tFFTout, TWindowContainer& tWindow, *someparams*) {;


#pragma omp parallel for shared(tWindow) firstprivate(sFFTParams) reduction(complexMul: tFFTin) ordered if(iFFTRawDataLen>cMinParallelSize)
for (int p = 0; p < uPolyphase; ++p) {
int iPolyphaseOffset = p * uFFTLength;
for (int i = 0; i < uFFTLength; ++i) {
tFFTin[i] *= tWindow[iPolyphaseOffset + i]; ///< get FFT input data from raw data
}

#pragma omp ordered
{
//using the overlap and add method
for (int i = 0; i < sFFTParams.uFFTLength; ++i) {
pDataPool->GetFullSignalData(workSignal)[mSignalPos + iPolyphaseOffset + i] += tFFTin[i];
}
}

}

mSignalPos = mSignalPos + mStep;
}

是否存在竞争条件或其他原因,导致在开始时输出错误?还是我有什么逻辑错误?

另一个问题是,我不太喜欢我使用有序 pragma 的解决方案,有没有更好的方法(我也尝试为此使用缩减模型,但编译器不允许我使用指针类型)?

最佳答案

我认为你的问题是你已经为 tFFTin 实现了一个非常酷的自定义缩减。但是这种减少是在平行区域的末尾应用的。这是在您使用 tFFTin 中的数据之后。另一件事是 H. Iliev 提到的,外循环的第二次迭代依赖于在前一次迭代中计算的数据 - 一种经典的依赖性。

我认为您应该尝试并行化内部循环。

关于c++ - OpenMP 并行代码与串行代码的输出不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30889385/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com