簡體   English   中英

優化循環以獲得更好的性能

[英]Optimizing loop for better performance

我像這樣並行化我的代碼:

    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 指令,因為沒有它們,兩者都有相同的結果。

如果有人能給我一些關於如何使這成為可能或如何提高總體性能的提示,我會很高興。

無需重新設計代碼,您可以嘗試以下操作:

    #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];
      }
   }

您可以創建一個單獨的區域,而不是每次循環i迭代創建 2 次並行區域(總共 2 * 大小的並行區域)。 盡管如此,在 OpenMP 標准的有效實現中,新的並行區域不會引入人們可能認為的那么多開銷,因為通常線程將在第一次創建並在下一個並行區域上重用。

盡管如此,擁有多個並行區域的開銷之一是調用它們末尾的隱式屏障。 不幸的是,我展示的版本中仍然存在這種開銷。 為避免這種情況,您需要重新設計算法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM