[英]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);
}
一些注意事項:
除非確實需要異常安全索引std::vector::at
否則不要使用std::vector::at
。
您對每個向量使用相同的索引,因此從i=0
開始,而不是從Fortran風格i=1
。
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];
}
}
請注意,我假設nthreads
將M
nthreads
。 如果不是,則需要單獨處理這種情況。 如果您使用的是OpenMP 4.0,則我建議使用simd
指令,因為前兩行都是saxpy操作,可以從向量化中受益。 為了獲得最佳性能,請確保chunk_size
是CPU的緩存行大小的倍數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.