【问题标题】:Optimizing loop for better performance优化循环以获得更好的性能
【发布时间】:2021-05-10 15:28:04
【问题描述】:

我这样并行化我的代码:

    for (int i=0; i<size; ++i) {
    
        #pragma omp parallel for
        for (int j=i; j<size; ++j) {
            int l = j+1;
            float sum = a[i*size+j];
            float sum2 = a[l*size+i];
            for (int k=0; k<i; ++k) {
                sum -= a[i*size+k] * a[k*size+j];
                sum2 -= a[l*size+k] * a[k*size+i];
            }
            a[i*size+j]=sum;
            a[l*size+i]=sum2;
        }
        
        #pragma omp parallel for
        for (int j=i+1; j<size; ++j) {
            a[j*size+i]/=a[i*size+i];
        }
    }

但我希望它是这样的:

    for (int i=0; i<size; ++i) {
    
        #pragma omp parallel for
        for (int j=i; j<size; ++j) {
            int l = j+1;
            float sum = a[i*size+j];
            float sum2 = a[l*size+i];
            for (int k=0; k<i; ++k) {
                sum -= a[i*size+k] * a[k*size+j];
                sum2 -= a[l*size+k] * a[k*size+i];
            }
            a[i*size+j]=sum;
            a[l*size+i]=sum2;
            a[l*size+i]/=a[i*size+i];
        }
    }

这样我才能获得更好的表现。但是,如果我将a[l*size+i]/=a[i*size+i]; 放入与其他内容相同的循环中,我得到的结果与我应该得到的结果不同。我猜这是因为 OpenMP 指令,因为没有它们,两者的结果相同。

如果有人能给我一些关于如何实现这一点或如何提高总体性能的提示,我会很高兴。

【问题讨论】:

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


    【解决方案1】:

    无需重新设计代码,您可以尝试以下操作:

        #pragma omp parallel
        {
            for (int i=0; i<size; ++i)
            {
                #pragma omp for
                for (int j=i; j<size; ++j) {
                     int l = j+1;
                     float sum = a[i*size+j];
                     float sum2 = a[l*size+i];
                     for (int k=0; k<i; ++k) {
                         sum -= a[i*size+k] * a[k*size+j];
                         sum2 -= a[l*size+k] * a[k*size+i];
                     }
                    a[i*size+j]=sum;
                    a[l*size+i]=sum2;
                }
                #pragma omp for
                for (int j=i+1; j<size; ++j)
                    a[j*size+i]/=a[i*size+i];
          }
       }
    

    您可以创建一个并行区域,而不是创建 2 次 per 循环 i 迭代(总共 2 * 大小的并行区域)的并行区域。尽管如此,在 OpenMP 标准的有效实现中,新的并行区域不会引入人们可能认为的那么多开销,因为通常线程将在第一次创建并在下一个并行区域上重用。

    尽管如此,拥有多个并行区域的开销之一是调用它们末尾的隐式屏障。不幸的是,我展示的版本中仍然存在这种开销。为避免这种情况,您需要重新设计算法。

    【讨论】:

    • 非常感谢,它现在运行得更快了。我不知道这会有所作为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    相关资源
    最近更新 更多