gpt4 book ai didi

结合openmp和sse指令

转载 作者:太空宇宙 更新时间:2023-11-04 03:01:48 25 4
gpt4 key购买 nike

原始代码看起来像

for(i=0;i<20;i++){
if(){
do();
}
else{

num2 = _mm_set_pd(Phasor.imaginary, Phasor.real);

for(int k=0; k<SamplesIneachPeriodCeil[iterationIndex]; k++)
{
/*SamplesIneachPeriodCeil[iterationIndex] is in range of 175000*/

num1 = _mm_loaddup_pd(&OutSymbol[k].real);
num3 = _mm_mul_pd(num2, num1);
num1 = _mm_loaddup_pd(&OutSymbol[k].imaginary);
num2 = _mm_shuffle_pd(num2, num2, 1);
num4 = _mm_mul_pd(num2, num1);
num3 = _mm_addsub_pd(num3, num4);
num2 = _mm_shuffle_pd(num2, num2, 1);
num5 = _mm_set_pd(InSymbolInt8[k],InSymbolInt8[k] );
num6 = _mm_mul_pd(num3, num5);
num7 = _mm_set_pd(Out[k].imaginary,Out[k].real);
num8 = _mm_add_pd(num7,num6);
_mm_storeu_pd((double *)&Out[k], num8);

}
Out = Out + SamplesIneachPeriodCeil[iterationIndex];
}
}

这段代码给了我 ard 15milsec 的速度

当我修改代码以将 openmp 包含在内时

注意::这里我只包括其他部分

else{
int size = SamplesIneachPeriodCeil[iterationIndex];

#pragma omp parallel num_threads(2) shared(size)
{
int start,end,tindex,tno,no_of_iteration;
tindex = omp_get_thread_num();
tno = omp_get_num_threads();
start = tindex * size / tno;
end = (1+ tindex)* size / tno ;
num2 = _mm_set_pd(Phasor.imaginary, Phasor.real);
int k;
for(k = start ; k < end; k++){


num1 = _mm_loaddup_pd(&OutSymbol[k].real);
num3 = _mm_mul_pd(num2, num1);
num1 = _mm_loaddup_pd(&OutSymbol[k].imaginary);
num2 = _mm_shuffle_pd(num2, num2, 1);
num4 = _mm_mul_pd(num2, num1);
num3 = _mm_addsub_pd(num3, num4);
//_mm_storeu_pd((double *)&newSymbol, num3);
num2 = _mm_shuffle_pd(num2, num2, 1);
num5 = _mm_set_pd(InSymbolInt8[k],InSymbolInt8[k] );
num6 = _mm_mul_pd(num3, num5);
num7 = _mm_set_pd(Out[k].imaginary,Out[k].real);
num8 = _mm_add_pd(num7,num6);
_mm_storeu_pd((double *)&Out[k], num8);


}
}
Out = Out + size;
}

此代码显示的速度约为 30 毫秒

所以我想知道我是否在这里做错了什么。

最佳答案

您没有做任何事情来在两个线程之间分配循环的执行。您只是创建了一个具有两个线程的并行区域,并且这些线程执行完全相同的代码。您可能想要做的是移动平行区域以仅包含 for循环并使用工作共享结构:

int k;
#pragma omp parallel for num_threads(2) ...
for(k = start ; k < end; k++){
...
}

<罢工>

感谢 Tudor 的更正。您的代码已正确并行化,但您在循环内有一个并行区域。进入和退出并行区域会产生一些开销。通常这被描述为“fork/join 模型”,其中一组线程在进入区域时创建,然后所有线程在退出时连接到 master。大多数 OpenMP 运行时使用各种线程池技术来减少开销,但它仍然存在。

您的循环运行了 15 毫秒。与 OpenMP 开销相比,这已经足够快,因此开销变得可见。考虑将并行区域移到外循环上,开销应该减少最多 20 倍(取决于执行 else 分支的频率),但您可能仍然看不到计算时间的改善。

并行化仅适用于问题足够大以至于通信或同步开销与计算时间相比可以忽略不计或至少很小的程序。

关于结合openmp和sse指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10732487/

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