使用嵌套while循环并行化for循环时的OpenMP分段错误

时间:2018-05-10 12:17:37

标签: c++ parallel-processing openmp

我有一个for循环,它将总结两个变量'Time'和'successRuns',但循环内部运行的次数随机变化。 (我认为代码在这个问题上是自我解释的)

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

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

rnd()是一个返回0和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;

1 个答案:

答案 0 :(得分:1)

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

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

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

例如:

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: %d\n",myOnly);
    }
    printf("value : %d", var);
}

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

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

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

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

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

尝试组织变量并为线程创建本地(私有),因此一个线程没有机会覆盖它不应该的东西。