c-OpenMP中是否有默认的作用域分隔符



我是OpenMP的新手,刚刚完成了我的第一次尝试,它是矩阵乘法。我只是想知道openMP中是否存在默认的块分隔符?以下是我的代码:

#include <stdio.h>
#include <omp.h>
#define MAX_THREADS 4
#define ASIZE 500
int main()
{
  /*intialization of 2 matrix*/     
  long matrixa [ASIZE][ASIZE];
  long matrixb [ASIZE][ASIZE];
  long matrixc [ASIZE][ASIZE] = {0};
  for(int i=0; i<ASIZE; i++)
    for(int j=0;j<ASIZE; j++)
    {
      matrixa [i][j] = 1;
      matrixb [i][j] = j;
    }
  omp_set_num_threads(MAX_THREADS);
  #pragma omp parallel
  {
    long cprivate [ASIZE][ASIZE] = {0};
    #pragma omp for
    for(int i =0 ;i<ASIZE; i++)
      for(int j=0; j<ASIZE; j++)
        for(int k=0; k<ASIZE; k++)
          cprivate[i][j]+=matrixa[i][k]*matrixb[k][j];
    #pragma omp critical
    for(int i =0 ;i<ASIZE; i++)
      for(int j=0; j<ASIZE; j++)
        matrixc[i][j]+=cprivate[i][j];
    //#pragma omp barrier
    if(omp_get_thread_num() ==0)
      for(int i=0; i<50; i++)
        printf("Snap of C array %lu n", matrixc[1][i]); //print out chunk of the first row!
  }
}

我想这样做是因为无论我是否添加#pragma omp barrier,我都可以得到预期的结果,应该是#pragma omp critical块完全执行后的结果。

问题

@为什么有没有#pragma omp barrier没有区别?

@我还注意到,一旦我将数组大小增加到600,它在执行.o文件时会提醒分段错误,我最初猜测它来自int范围(我已将数组类型从int[]修改为long[]),没有区别。

您的代码可能会失败,因为您使用的是自动存储。您应该使用动态或静态存储。以下是使用静态存储修复代码的方法

#include <stdio.h>
#include <stdlib.h>
#define ASIZE 1000
long matrixa [ASIZE][ASIZE];
long matrixb [ASIZE][ASIZE];
long matrixc [ASIZE][ASIZE]; //set to zero by default with static storage
int main() {
    for(int i=0; i<ASIZE; i++) {
        for(int j=0;j<ASIZE; j++) {
            matrixa [i][j] = 1;
            matrixb [i][j] = j;
        }
    }
    #pragma omp parallel for
    for(int i=0 ;i<ASIZE; i++) {
        for(int j=0; j<ASIZE; j++) {
            long sum = 0;
            for(int k=0; k<ASIZE; k++) {
                sum += matrixa[i][k]*matrixb[k][j];
            }
            matrixc[i][j] = sum;
        }
    }
    for(int i=0; i<50; i++) printf("Snap of C array %lu n", matrixc[1][i]);
}

如果您想要为每个线程静态分配缓冲区,则需要使用threadprivate,否则使用动态分配。

不需要使用屏障的原因是critical和许多其他构造隐含了屏障。为了消除隐性障碍,在某些情况下可以使用nowait(例如#pragma omp parallel for nowait)。

相关内容

  • 没有找到相关文章

最新更新