C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了OpenMP中可重用的私有动态分配数组大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用OpenMP和MPI来并行化c中的一些矩阵运算.在矩阵上运行的一些函数是用Fortran编写的. Fortran函数需要传递一个缓冲区数组,该数组仅在函数内部使用.目前我在每个并行部分分配缓冲区,类似于下面的代码.

int i = 0;
int n = 1024; // Actually this is read from command line
double **a = createNbyNMat(n);
#pragma omp parallel
{
    double *buf;
    buf = malloc(sizeof(doublE)*n);
#pragma omp for
    for (i=0; i < n; i++)
    {
        fortranFunc1_(a[i],&n,buf);
    }
    free(z);
}

// serial code and moving data around in the matrix a using MPI

#pragma omp parallel
{
    double *buf;
    buf = malloc(sizeof(doublE)*n);
#pragma omp for
    for (i=0; i < n; i++)
    {
        fortranFunc2_(a[i],buf);
    }
    free(z);
}

// and repeat a few more times.

我知道使用类似于下面的代码方法可以避免重新分配缓冲区,但我很好奇是否有更简单的方法或OpenMP中的一些内置功能来处理这个问题.无论是否在我们正在编译的系统上存在OpenMP,能够在没有大量编译器指令的情况下编译代码将是很好的.

double **buf;
buf = malloc(sizeof(double*) * num_openmp_threads);
int i = 0;
for (i = 0; i < num_openmp_threads; ++i)
{
    buf[i] = malloc(sizeof(doublE) * n);
}

// skip ahead

#pragma omp for
for (i=0; i < n; i++)
{
    fortranFunc1_(a[i],buf[current_thread_num]);
}

解决方法

可以使用线程私有变量来完成它.那些在后续的并行区域中持续存在:

void func(...)
{
   static double *buf;
   #pragma omp threadprivate(buf)

   #pragma omp parallel num_threads(nth)
   {
       buf = malloc(n * sizeof(doublE));
       ...
   }

   #pragma omp parallel num_threads(nth)
   {
       // Access buf here - it is still allocated
   }

   #pragma omp parallel num_threads(nth)
   {
       // Free the memory in the last parallel region
       free(buf);
   }
}

这里有几个要点需要注意.首先,分配buf的线程数应该与解除分配它的线程数相匹配.此外,如果中间存在并行区域并且它们与较大的团队一起执行,则可能不会在所有区域中分配buf.因此,建议您禁用OpenMP的动态团队大小功能,或者只使用上面显示的num_threads子句来修复每个并行区域的线程数.

其次,局部变量只有在静态时才能成为线程私有的.因此,该方法不适用于递归函数.

即使禁用了OpenMP支持,代码也应按预期编译和工作.

大佬总结

以上是大佬教程为你收集整理的OpenMP中可重用的私有动态分配数组全部内容,希望文章能够帮你解决OpenMP中可重用的私有动态分配数组所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。