omp 库 c++ pragma for

问题描述 投票:0回答:1

我有这段代码,但我需要帮助来使用 OpenMP

#pragma
s 来提高其速度。我想在变量
for
i
上并行化
j
循环。
n
m
的值也可以大得多。例如,
n = 1000
m = 500

我的代码:

for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
        matrix[i][j] = {static_cast<double>(distribution(gen)), static_cast<double>(distribution(gen))};
    }
}

 #pragma omp parallel
 {
    n = 50; m=50; ReS=0; ImS=0;
    
    for(int nu = 0; nu < 1; nu++)
    {
    #pragma omp for num_threads(4)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            double* matrixPtr = &matrix[i][j].first;
            double* matrixPtrSecond = &matrix[i][j].second;

            for (double theta = 0; theta < PI; theta += theta_plus) 
                {
                for (double phi = 0; phi < 2 * PI; phi += theta_plus) 
                    {
                    double angle = *matrixPtr * cos(phi) * sin(theta) + *matrixPtrSecond * sin(phi) * sin(theta);
                    ReS += cos(angle);
                    ImS += sin(angle);
                    }
                }
            }
        }
    }
 }
c++ parallel-processing openmp pragma
1个回答
0
投票

那个

#pragma omp parallel
{
    // ...

在您的原始代码中,导致整个关联块由团队线程的each并行执行。这似乎适得其反。至少,意图尚不清楚。

...

for(int nu = 0; nu < 1; nu++)

...循环无条件地执行一次迭代。这似乎毫无意义。

主要计算对共享变量

ReS
ImS
执行频繁更新。这绝对是性能杀手,但该结构非常适合使用归约来解决该问题。

您说过(我认为)您想要并行化

i
j
上的循环。您提供的代码仅并行化其中的外部,但当然带有内部循环。循环结构与
(i,j)
对上的并行化兼容,而不是仅在
i
上并行化,所以我将在下面展示这一点,尽管我绝不确定这会产生很大的差异。

这可能适用于主循环:

#if 0
 // Remove this
 #pragma omp parallel
 {
#endif
n = 50;
m = 50;
ReS = 0;
ImS = 0;

#pragma omp parallel for collapse(2) num_threads(4) reduction(+:ReS,ImS)
for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
        double *matrixPtr = &matrix[i][j].first;
        double *matrixPtrSecond = &matrix[i][j].second;

        for (double theta = 0; theta < PI; theta += theta_plus) {
            for (double phi = 0; phi < 2 * PI; phi += theta_plus) {
                double angle = *matrixPtr * cos(phi) * sin(theta)
                             + *matrixPtrSecond * sin(phi) * sin(theta);
                ReS += cos(angle);
                ImS += sin(angle);
            }
        }
    }
}
#if 0
}
#endif

也可能有机会大幅加快计算的串行版本,正如问题评论中所讨论的那样,但我在这里重点关注 OpenMP 指令的使用,这就是问题似乎要问的内容。

© www.soinside.com 2019 - 2024. All rights reserved.