c - OpenMP 和共享结构和指针

标签 c shared shared-memory openmp

我有一个函数,它通过引用传递两个结构。这些结构由动态分配的数组组成。现在,当我尝试实现 OpenMP 时,速度变慢了,而不是加速了。我认为这可以归因于可能的共享问题。以下是供您细读的一些代码 (C):

void    leap(MHD *mhd,GRID *grid,short int gchk)
{
  /*-- V A R I A B L E S --*/
  // Indexes
  int i,j,k,tid;
  double rhoinv[grid->nx][grid->ny][grid->nz];
  double rhoiinv[grid->nx][grid->ny][grid->nz];
  double rhoeinv[grid->nx][grid->ny][grid->nz];
  double rhoninv[grid->nx][grid->ny][grid->nz]; // Rho Inversion
  #pragma omp parallel shared(mhd->rho,mhd->rhoi,mhd->rhoe,mhd->rhon,grid,rhoinv,rhoiinv,rhoeinv,rhoninv) \
                       private(i,j,k,tid,stime)
  {
    tid=omp_get_thread_num();
    printf("-----  Thread %d Checking in!\n",tid);
    #pragma omp barrier
    if (tid == 0)
    {
      stime=clock();
      printf("-----1) Calculating leap helpers");
    }
    #pragma omp for
    for(i=0;i<grid->nx;i++)
    {
      for(j=0;j<grid->ny;j++)
      {
        for(k=0;k<grid->nz;k++)
        {
          //      rho's
          rhoinv[i][j][k]=1./mhd->rho[i][j][k];
          rhoiinv[i][j][k]=1./mhd->rhoi[i][j][k];
          rhoeinv[i][j][k]=1./mhd->rhoe[i][j][k];
          rhoninv[i][j][k]=1./mhd->rhon[i][j][k];
        }
      }
    }
    if (tid == 0)
    {
      printf("........%04.2f [s] -----\n",(clock()-stime)/CLOCKS_PER_SEC);
      stime=clock();
    }
    #pragma omp barrier
  }/*-- End Parallel Region --*/
}

现在我已经尝试了 default(shared) 和 shared(mhd),但都没有任何改善的迹象。难道是因为数组被分配了

mhd->rho=(double ***)newarray(nx,ny,nz,sizeof(double));

通过声明结构或指向结构元素的指针,我实际上并没有共享内存,只是共享指向它的指针?哦,在这个例子中 nx=389 ny=7 和 nz=739。对于 8 个线程,此部分的串行执行时间为 0.23 [s] 和 0.79 [s]。

最佳答案

我的问题归结为一个真正简单的错误....clock()。虽然我确实通过仅让特定线程计算时间来保护我的计时算法,但我忘记了关于 clock() 的一件重要事情......它返回挂钟时间,即总处理器时间(事件线程的总和)。我需要调用的是 omp_get_wtime()。这样做我突然发现我的代码的许多部分都在加速。作为记录,我修改了我的代码以包含

#ifdef _OPENMP
    #include <omp.h>
    #define TIMESCALE 1
#else
    #define omp_get_thread_num() 0
    #define omp_get_num_procs() 0
    #define omp_get_num_threads() 1
    #define omp_set_num_threads(bob) 0
    #define omp_get_wtime() clock()
    #define TIMESCALE CLOCKS_PER_SEC
#endif

现在我的计时算法是

    #pragma omp barrier
    if (tid == 0)
    {
        stime=omp_get_wtime();
        printf("-----1) Calculating leap helpers");
    }
    #pragma omp for
    for(i=0;i<grid->nx;i++)
    {
        for(j=0;j<grid->ny;j++)
        {
            for(k=0;k<grid->nz;k++)
            {
                //      rho's
                rhoinv[i][j][k]=1./mhd->rho[i][j][k];
                rhoiinv[i][j][k]=1./mhd->rhoi[i][j][k];
                rhoeinv[i][j][k]=1./mhd->rhoe[i][j][k];
                rhoninv[i][j][k]=1./mhd->rhon[i][j][k];
                //  1./(gamma-1.)
                gaminv[i][j][k]=1./(mhd->gamma[i][j][k]-1.);
                gamiinv[i][j][k]=1./(mhd->gammai[i][j][k]-1.);
                gameinv[i][j][k]=1./(mhd->gammae[i][j][k]-1.);
                gamninv[i][j][k]=1./(mhd->gamman[i][j][k]-1.);
            }
        }
    }
    if (tid == 0)
    {
        printf("........%04.2f [s] -----\n",(omp_get_wtime()-stime)/TIMESCALE);
        stime=omp_get_wtime();
        printf("-----2) Calculating leap helpers");
    }

关于c - OpenMP 和共享结构和指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4044889/

相关文章:

windows - 在windows中查找内存映射对象的列表

boost - 在 Boost Jam 文件中将多个静态库组合成单个共享库

c++ - 写入共享内存的频率限制?

c++ - 我应该使用相同的 VBO 来传递不同的顶点属性吗?或者我应该使用 2?

c++ - 提取共享内存的大小

c - Linux C : Accessing shared memory fails with `Invalid Argument` even though it was just created

c - 防止命令提示符在代码运行后关闭

c - x=0x80000000时~(x-1)和~x+1的区别

c - 编码 AVR ATmega32 和 Arduino Mega 之间的主要区别是什么?

C 中的条件运算符