gpt4 book ai didi

c++ - 使用 OpenMP 进行归约以计算矩阵元素的最终求和值

转载 作者:行者123 更新时间:2023-12-02 01:56:14 25 4
gpt4 key购买 nike

我有以下双循环,我在其中计算矩阵 Fisher_M[FX][FY] 的元素。

我试图通过放置一个 OMP pragma #pragma omp parallel for schedule(dynamic, num_threads) 来优化它,但效果不如预期。

有没有一种方法可以使用 OpenMP(总和)进行归约以快速计算元素 Fisher_M[FX][FY]?或者也许这可以通过 MAGMA 或 CUDA 实现?

#define num_threads 8

#pragma omp parallel for schedule(dynamic, num_threads)
for(int i=0; i<CO_CL_WL.size(); i++){
for(int j=0; j<CO_CL_WL.size(); j++){
if( CO_CL_WL[i][j] != 0 || CO_CL_WL_D[i][j] != 0){
Fisher_M[FX][FY] += CO_CL_WL[i][j]*CO_CL_WL_D[i][j];
}
}
}

最佳答案

您的代码在行 Fisher_M[FX][FY] += ... 处存在竞争条件。可以用reduce来解决:

double sum=0;  //change the type as needed
#pragma omp parallel for reduction(+:sum)
for(int i=0; i<CO_CL_WL.size(); i++){
for(int j=0; j<CO_CL_WL.size(); j++){
if( CO_CL_WL[i][j] != 0 || CO_CL_WL_D[i][j] != 0){
sum += CO_CL_WL[i][j]*CO_CL_WL_D[i][j];
}
}
}
Fisher_M[FX][FY] += sum;

请注意,此代码受内存限制,计算量不大,因此并行化带来的性能增益可能小于预期(并且取决于您的硬件)。

Ps:为什么需要这个条件if( CO_CL_WL[i][j] != 0 || CO_CL_WL_D[i][j] != 0)?如果其中任何一个为零,则总和不会改变。如果删除它,编译器可以生成更好的矢量化代码。

Ps2:在 schedule(dynamic, num_threads) 子句中,第二个参数是 block 大小而不是使用的线程数。我建议根据您的情况将其删除。如果您希望指定使用的线程数,请添加num_threads 子句或使用omp_set_num_threads 函数。

关于c++ - 使用 OpenMP 进行归约以计算矩阵元素的最终求和值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69584565/

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