我有以下代码:
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
。每个向量使用相同的索引,因此从
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
。如果不是,则需要单独处理这种情况。如果使用的是OpenMP 4.0,则我建议使用simd
指令,因为前两行都是saxpy操作,可以从向量化中受益。为了获得最佳性能,请确保chunk_size
是CPU的缓存行大小的倍数。关于c++ - 在openmp中进行for循环,与矩阵/vector 操作并行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38382272/