【问题标题】:OpenMP - "#pragma omp critical" importanceOpenMP - “#pragma omp critical”重要性
【发布时间】:2021-09-07 09:04:22
【问题描述】:

所以我开始使用 OpenMP(多线程)来提高矩阵乘法的速度,并且我目睹了奇怪的事情:当我关闭 OpenMP 支持(在 Visual Studio 2019 中)我的嵌套-loop 完成速度提高了 2 倍。 所以我删除了“#pragma omp critical”来测试它是否会显着减慢进程并且 进程比以前快 4 倍(使用 OpenMP 支持 开)。

这是我的问题:“#pragma omp critical”在嵌套循环中重要吗?我不能跳过它吗?

        #pragma omp parallel for collapse(3)
        for (int i = 0; i < this->I; i++)
        {
            for (int j = 0; j < A.J; j++)
            {
                m.matrix[i][j] = 0;
                for (int k = 0; k < A.I; k++)
                {   
                        #pragma omp critical
                        m.matrix[i][j] += this->matrix[i][k] * A.matrix[k][j];                                            
                }
            }
        }

【问题讨论】:

    标签: c++ multithreading performance parallel-processing openmp


    【解决方案1】:

    这是我的问题:“#pragma omp critical”在嵌套中是否重要 环形?我不能跳过它吗?

    如果矩阵m、this 和A 不同,则不需要任何临界区。相反,您需要确保每个线程将写入矩阵m 的不同位置,如下所示:

           #pragma omp parallel for collapse(2)
            for (int i = 0; i < this->I; i++)
            {
                for (int j = 0; j < A.J; j++)
                {
                    m.matrix[i][j] = 0;
                    for (int k = 0; k < A.I; k++)
                    {   
                        m.matrix[i][j] += this->matrix[i][k] * A.matrix[k][j];                                            
                    }
                }
            }
    

    collapse 子句将为每个线程分配不同的对 (i, j),因此不会有多个线程写入矩阵 m 的同一位置(即竞争条件)。

    【讨论】:

    • 谢谢你的解释:)我会用你的方法
    【解决方案2】:

    #pragma omp critical 在这里是必需的,因为两个线程有​​可能(远程)写入特定的m.matrix[i][j] 值。这会损害性能,因为一次只有一个线程可以访问该受保护的赋值语句。

    如果没有collapse 部分,这可能会更好(然后您可以删除#pragma omp critical)。将总和累加到一个临时局部变量,然后在 k 循环结束后将其存储在 m.matrix[i][j] 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 2016-05-03
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 2021-03-22
      • 2021-07-31
      相关资源
      最近更新 更多