我对使用OpenMP并行化for循环感兴趣,其中涉及全局std向量。
在这个具体的例子中,执行操作vec[1] = vec[1] + i
的顺序并不重要,但有时由于竞争条件,结果似乎是错误的。处理这个问题的正确方法是什么?
REDUCTION子句似乎不适用于容器。
#include <iostream>
#include <vector>
std::vector<double> vec = {1,1};
void func(int i){
vec[1] = vec[1] + i;
}
int main(int argc, char *argv[]) {
int k;
#pragma omp parallel for
for(k=1; k<10; k++){
func(k);
}
std::cout << vec[0] << ", " << vec[1] << std::endl;
}
答案 0 :(得分:2)
问题在于行
auto tmp = vec[1];
tmp = tmp + i;
vec[1] = tmp
不是原子的。编译时,它看起来更像是
vec[1] = vec[1] + i;
在这种情况下,你有一个竞争条件。
如果你想这样做,你可以告诉OpenMP你的#include <iostream>
#include <vector>
std::vector<double> vec = {1,1};
void func(int i){
#pragma omp atomic
vec[1] = vec[1] + 1;
}
int main(int argc, char *argv[]) {
int k;
#pragma omp parallel for
for(k=1; k<100; k++){
func(k);
}
std::cout << vec[0] << ", " << vec[1] << std::endl;
}
应该是原子的,如下所示:
{{1}}