在OpenMP中使用任务指令的正确方法是什么

时间:2013-11-02 12:16:22

标签: c openmp

我正在尝试使用OpenMP任务将两个矩阵相乘。这是一个基本代码:

long i, j, k;

   for (i = 0; i < N; i ++)
      for (j = 0; j < N; j ++)
         for (k = 0; k < N; k ++)
            c[i * N + j] += a[i * N + k] * b[k * N + j];

所以,我想在列级别上使用任务,然后我修改了这样的代码:

   long i, j, k;
#pragma omp parallel 
{
   #pragma omp single
   {
   for (i = 0; i < N; i ++)
     #pragma omp task private(i, j, k)
     {
      for (j = 0; j < N; j ++)
         for (k = 0; k < N; k ++)

            c[i * N + j] += a[i * N + k] * b[k * N + j];
      }
    }
  }

当我运行程序时,我得到这样的消息:

  

分段错误(核心转储)

现在,我知道我错过了一些,但无法弄清楚是什么。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

OpenMP中的

private变量未初始化且具有随机初始值。当任务执行时,i将具有随机值,因此可能导致对c[]a[]的越界访问。

firstprivate变量与private类似,但其初始值设置为引用变量在输入构造时的值。在您的情况下,i必须是firstprivate而不是private

同样建议i在并行区域中private,以提高性能。因此,最终代码应如下所示(所有变量共享类都是显式编写的,私有变量在其使用范围内声明):

#pragma omp parallel shared(a, b, c)
{
   #pragma omp single
   {
      long i;
      for (i = 0; i < N; i++)
         #pragma omp task shared(a, b, c) firstprivate(i)
         {
            int j, k;
            for (j = 0; j < N; j++)
               for (k = 0; k < N; k++)
                  c[i * N + j] += a[i * N + k] * b[k * N + j];
         }
   }
}