将 for 循环与嵌套的 while 循环并行化时出现 OpenMP 分段错误



我有一个for循环,它将汇总两个变量,"Time"和"successRuns",但循环将运行的次数在循环内随机更改。(我认为代码在这件事上是自我解释的(

问题是我一直收到分段错误错误。不使用 openmp 时不会发生这种情况。

这是我尝试并行运行的循环。

rnd(( 是一个返回 0 和 1 之间的随机数的函数。

#pragma omp parallel for
for(w=1; w<=200000; w++){
tau=0;
for(i=0; i<N; i++) g[i]=1;
g[0] = 2;
N_a=N-1;
N_b=1;
b=false;
while(b== false){
tau++;
R = rnd() * (N_a + N_b*r_b);    
prev=0; next=0;
chosenB = N;
for(i=0; i<N; i++){
if(g[i]==1) next = prev + 1.0;
else next = prev + r_b;
if(R>prev && R<next){
chosenB = i; break;
}
prev = next;
}
R = rnd() * N;
while(int(R)==chosenB)
R = rnd() * N;      
if(g[int(R)]==1) N_a--;
else N_b--;
g[int(R)] = g[chosenB];     
if(g[chosenB] == 1) N_a++;
else N_b++;
if(N_b == N){
b = true; break;
}
if(N_b == 0){
b = false; break;
}
}
if(g[0]==2 && b==true){     
Time += tau;
successRuns++;
}
if(b==false) w--;
runs++;
}
//end of parallel
cout<<Time/successRuns<<endl;
cout<<successRuns/runs<<endl;

查看您的代码,似乎所有变量都在线程之间共享/可见。

因此,不幸的是,由于并行竞争条件,无法预测代码执行过程中发生的情况。

争用条件是当执行线程位于代码的不同部分时,在您不需要时更改变量值。导致不可预测的结果。

例如:

int main(){
int var=0;    //shared variable, visible to all threads
#pragma omp parallel
{
int myOnly;    //private variable, each thread have it's own
if ( var <= 0)
var++;
else
var--;
myOnly = var;
printf("private variable: %dn",myOnly);
}
printf("value : %d", var);
}

假设我们这里有 2 个正在运行的线程,如果第一个线程执行if()检查并在第二个线程执行if()检查之前到达var++,则第二个线程将输入else代码(而不是if(。

但是如果第二个线程在第一个线程更改var的值之前检查if()语句,它将执行var++;,而不是var--;

这样,myOnly 的值只能在一个线程上为 -1 或 1,具体取决于发生了什么。

我们怎么知道其中之一会发生?我们没有。 每个线程都是独立运行的,无法预测会发生什么。

为此,有#pragma omp barrier和其他并行同步工具,但它们非常昂贵。

尝试组织变量并为线程创建局部(私有(变量,这样就没有机会一个线程覆盖不应该覆盖的东西。

最新更新