我如何将 openMP 用于我的代码?

Posted

技术标签:

【中文标题】我如何将 openMP 用于我的代码?【英文标题】:how can i use openMP for my code? 【发布时间】:2015-01-19 16:24:43 【问题描述】:

我从 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;
    

我怎样才能正确地做到这一点?我需要你的帮助。

【问题讨论】:

你认为你做错了什么? 首先正确缩进您的代码并添加空格。不要使用变量名l,因为它与1 很难区分;它在自找麻烦。 也许h, i,j,p,lmin 也应该是私有的:每个线程都应该处理自己的h,i,j,lmin 值。 【参考方案1】:

您现在缺少几个方面:

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

#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变量相同的名称所掩盖。现在我不确定你是否真的需要更改变量的名称——我假设你不需要——但这是个好主意。此外,正如您在 cmets 中已经告知的那样,尽量避免使用字母 'l' 作为变量名,因为它看起来像数字 1。

(*) 在 C 的早期版本的 OpenMP 中,您没有最小/最大减少,因此您必须在每个线程的私有变量中存储 min 的临时值,然后在之后找到全局最小值循环,在关键部分内或使用原子操作。

【讨论】:

以上是关于我如何将 openMP 用于我的代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中进行并行编程?

OpenMP 代码帮助

OpenMP 并行代码与串行代码的输出不同

无法理解 OpenMP 代码中的一些意外行为

将静态库链接到共享库(例如openmp)是一个好主意

如何提高 OpenMP 代码的性能?