我如何使用openMP代码?

时间:2015-01-19 16:24:44

标签: c++ c multithreading parallel-processing openmp

我从openMP开始,我希望并行化这部分代码

int A[n][m+1];
int B[k][m];
for (h=0;h<100;h++){
    for (i=0;i<n;i++){p=0;
        for (j=0;j<k;j++){s=0;
            for (l=0;l<m;l++){
                 s+=(A[i][l]-B[j][l]);
             }
          s=sqrt(s);    
          if (j==0) min =s;
           else
            if (min > s){min =s;p=j;}              
       }
    A[i][m]=p;
    }
}

这是我尝试使用openMP进行并行化

#pragma omp parallel for private(s)
 for (h=0;h<100;h++){
    for (i=0;i<n;i++){p=0;
        for (j=0;j<k;j++){s=0;
            for (l=0;l<m;l++){
                 s+=(A[i][l]-B[j][l]);
             }
          s=sqrt(s);    
          if (j==0) min =s;
           else
            if (min > s){min =s;p=j;}              
       }
    A[i][m]=p;
    }
}

我该怎么做才能正确?我需要你的帮助。

1 个答案:

答案 0 :(得分:0)

你现在缺少几个方面:

私有与共享变量:您不能让多个线程使用相同的变量作为循环计数器或任何其他类型的辅助变量。如果一个线程修改了另一个线程的循环计数器,那么就会出现混乱。解决方案:指定共享哪些变量以及哪些变量是私有的:

#pragma omp parallel for private(s, min, h, i, j, l) shared(n, k, m)

减少:您正在对变量'min'执行减少操作。从OpenMP 3.1和gcc 4.7开始,您可以让OpenMP为您(*)处理此减少:

#pragma omp parallel for reduction(min : min) private(s, h, i, j, l) shared(n, k, m)
// here the rest of your code

这一特定语法被操作min(最小)和min变量的名称相同所掩盖。现在我不确定你是否真的需要更改变量的名称 - 我假设你不需要 - ,但不过这是一个好主意。此外,正如您在评论中已经告知的那样,尽量避免使用字母'l'作为变量名,因为它看起来像数字1。

(*)在早期版本的OpenMP in C中,你没有最小/最大缩减,所以你必须在每个线程的私有变量中存储min的临时值,然后找到全局循环后的最小值,在临界区内或使用原子操作。