簡體   English   中英

在openmp中進行for循環,與矩陣/向量操作並行

[英]Make a for loop in openmp, parallel with matrix/vector manipulations

我有以下代碼:

scalar State::add(const int N, const int M,                                                                                                                                                                                                                                               
                        vector<scalar>& flmn,                                                                                                                                                                                                                                             
                        vector<scalar>& BSum,                                                                                                                                                                                                                                             
                        const vector<scalar>& prev_flm,                                                                                                                                                                                                                                   
                        const vector<scalar>& prev_bigsum,                                                                                                                                                                                                                                
                        const vector<scalar>& Qratio,                                                                                                                                                                                                                                     
                        const int test)                                                                                                                                                                                                                                                   
{                                                                                                                                                                                                                                                                                         
  scalar c=1;                                                                                                                                                                                                                                                                          
  #pragma omp parallel for                                                                                                                                                                                                                                                                
  for(int i=1;i<=M;i++)                                                                                                                                                                                                                                                                   
   {                                                                                                                                                                                                                                                                                      
     flmn.at(i-1) = Qratio.at(i-1)*k1+k2;                                                                                                                                                                                                                                                 
     BSum.at(i-1) = someconstant + somepublicvector.at(1)*flmn.at(i-1);                                                                                                                                                                                                                   
     c *= BSum.at(i-1);                                                                                                                                                                                                                                                                   
   }                                                                                                                                                                                                                                                                                      
   return c;                                                                                                                                                                                                                                                                              
}                                                                                                                                                                                                                                                                                         

最后我要返回變量c 使用以下命令時:“ #pragma omp parallel for ”肯定不會給我一致的答案,因為迭代之間總是存在重疊。 我不知道如何在openmp中並行處理矩陣或矢量操作的這種組合,並且由於這里顯然存在競爭條件問題,我是否還會得到一致的結果?

for (int i = 1; i <= M; i++) {
    flmn.at(i - 1) = Qratio.at(i - 1) * k1 + k2;
    BSum.at(i - 1) = someconstant + somepublicvector.at(1) * flmn.at(i - 1);
    c *= BSum.at(i - 1);
}

一些注意事項:

  1. 除非確實需要異常安全索引std::vector::at否則不要使用std::vector::at

  2. 您對每個向量使用相同的索引,因此從i=0開始,而不是從Fortran風格i=1

  3. M是否與所使用向量的大小不同(即,它是一個子集)? 如果不是,則無需指定。


然后可能的OpenMP實現是

scalar c{1.0};

#pragma omp parallel
{
    const std::size_t nthreads = omp_get_num_threads();
    const std::size_t chunk_size = M / nthreads;    // WARNING: non-even division case left to user
    const std::size_t tid = omp_get_thread_num();

    #pragma omp for reduction(*:c)
    for (std::size_t j = 0; j < chunk_size; j++) {
        const std::size_t i = j + tid * chunk_size;
        flmn[i] = Qratio[i] * k1 + k2;
        BSum[i] = someconstant + somepublicvector[1] * flmn[i];
        c *= BSum[i];
    }
}

請注意,我假設nthreadsM nthreads 如果不是,則需要單獨處理這種情況。 如果您使用的是OpenMP 4.0,則我建議使用simd指令,因為前兩行都是saxpy操作,可以從向量化中受益。 為了獲得最佳性能,請確保chunk_size是CPU的緩存行大小的倍數。

暫無
暫無

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

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