openacc 与 openmp 和 mpi 的区别?

Posted

技术标签:

【中文标题】openacc 与 openmp 和 mpi 的区别?【英文标题】:openacc vs openmp & mpi differences ? 【发布时间】:2013-10-29 23:03:36 【问题描述】:

我想知道 openacc 和 openmp 之间的主要区别是什么。 MPI、cuda 和 opencl 呢? 我了解 openmp 和 mpi 之间的区别,尤其是关于共享和分布式内存的部分 它们中的任何一个都允许混合 gpu-cpu 处理设置吗?

【问题讨论】:

【参考方案1】:

OpenMP 和 OpenACC 支持基于指令的并行编程。

OpenMP 支持在共享内存计算平台上进行并行编程,例如多核 CPU。它非常易于使用,因为它足以告诉编译器一些指令(代码注释或 pragma)如何提取触发合成输入源代码的并行版本的并行性。

以下是带有编译指示的 OpenMP“Hello World”程序示例

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) 

  int nthreads, tid;

  /* Fork a team of threads giving them their own copies of variables */
  #pragma omp parallel private(nthreads, tid)

  
     /* Obtain thread number */
     tid = omp_get_thread_num();
     printf("Hello World from thread = %d\n", tid);

     /* Only master thread does this */
     if (tid == 0) 
     
        nthreads = omp_get_num_threads();
        printf("Number of threads = %d\n", nthreads);
     

    /* All threads join master thread and disband */


以上代码的来源是OpenMP Exercise,您可以从中找到许多其他示例。在这个“Hello World”示例中,主线程将输出涉及的线程数,而每个线程将打印 Hello World from thread = xxx

OpenACC 是一组编译器指令,用于指定 C/C++ 或 Fortran 代码的一部分,由附加的加速器(作为 GPU)进行加速。它遵循与 OpenMP 几乎相同的理念,并且能够创建高级主机+加速器程序,同样无需管理加速器编程语言。例如,OpenACC 可以让您简单地加速现有的 C/C++ 代码,而无需学习 CUDA(当然会有一些性能损失)。

典型的 OpenACC 代码如下所示

#pragma acc kernels loop gang(32), vector(16)
for (int j=1; j<n-1; j++)

#pragma acc loop gang(16), vector(32)
    for (int i=1; i<m-1; i++)
    
       Anew[j][i] = 0.25f * (A[j][i+1] + A[j-1][i]);
       ...
    
    

以上源代码取自博客An OpenACC Example (Part 1),您可以在其中找到一些更有用的资料来了解 OpenMP 和 OpenACC 之间的区别。

其他来源如下

How does the OpenACC API relate to the OpenMP API?.

OpenACC and OpenMP directives

Shane Cook,CUDA 编程,Morgan Kaufmann(第 10 章)

由于其本质,OpenACC 支持混合 CPU+GPU 编程。您还可以混合使用 OpenMP 和 OpenACC 指令。例如,在一个 4-GPU 系统中,您可以创建 4 个 CPU 线程来将计算工作卸载到 4 个可用的 GPU。这在 Shane Cook 的书中有所描述。但是,应该提到的是,OpenMP 4.0 还预见了将工作卸载到附加加速器的指令,请参阅

OpenMP Technical Report 1 on Directives for Attached Accelerators

【讨论】:

所以基本上这个时候OpenACC和OpenMP是相辅相成的。我对 OpenACC 了解不多,但我被引导相信的是 OpenACC 可以生成具有 cpu-gpu 混合处理的程序,但 openMP 不能做到这一点(仅限于与多核机器一起使用) @Sid5427 我已经扩展了我的答案。你说得对,OpenACC 支持混合 CPU+GPU 编程。还要考虑到 OpenMP 4.0 还预见到附加加速器的指令,请参阅OpenMP Technical Report 1 on Directives for Attached Accelerators。 啊是的。感谢您的扩展!我现在明白了。习惯了 OpenMP,正在考虑与 CUDA 合作,偶然发现了 OpenACC。 How does the OpenACC API relate to the OpenMP API? 坏了【参考方案2】:

OpenAcc 和 OpenMPI 支持基于指令的并行计算。 OpenMPI 尝试利用多个 CPU 内核,OpenAcc 尝试利用 GPU 内核。

MPI——消息解析接口,是集群中节点间和节点内通信的编程模型规范。 MPI程序的进程有一个私有的地址空间,它允许程序运行在一个分布式的内存空间(集群)上。 MPI 通常用于高性能计算,其中使用高带宽和低延迟的通信协议(如 Infiniband 等)。

随着 CUDA 和 OpenMP 等并行计算技术的最新发展,MPI 在其规范中添加了一些特性,以利用 cpu/gpu 内核提供的并行计算。

CUDA-Aware-MPI 和/或混合编程模型 (MPI + OpenMP) 已在使用中。这意味着最终应用程序程序员可以编写相同的 MPI 程序,而无需显式处理 CUDA 或 OpenMP。这减轻了最终用户的负担。

对于没有 CUDA_aware-GPU 的示例,MPI_Send 的代码 d MPI_Recv 就像

//MPI rank 0
cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);
MPI_Send(s_buf_h,size,MPI_CHAR,1,100,MPI_COMM_WORLD);

//MPI rank 1
MPI_Recv(r_buf_h,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status);
cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);

但使用 CUDA_awre_MPI

//MPI rank 0
MPI_Send(s_buf_d,size,MPI_CHAR,1,100,MPI_COMM_WORLD);

//MPI rank n-1
MPI_Recv(r_buf_d,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status);

MPI 库将解决将主机内存缓冲区转换为 GPU 缓冲区的问题。

【讨论】:

这个答案有很多错误和可怕之处:OpenMPI 是 MPI 标准的实现,它不是基于指令的。不要将 OpenMP 与 OpenMPI 混淆。 MPI 没有在其标准中引入任何规范来应对 GPU:CUDA 感知能力是 MPI 实现的选择,与 MPI 标准无关。我认为您应该完善您的答案并对该主题有更深入的了解。【参考方案3】:

阅读共享和分布式范式,您的问题可以在两个研究生级别的课程中得到更详细的回答, 如果您真的对以下领域感兴趣,我建议您参加 TACC(德克萨斯高级计算中心)夏季培训 动手学习

【讨论】:

这个问题很老了!目前,我已经大量参与了 TACC、Pegasus WMS、Cyverse 和其他超级计算资源的工作。 从地理上讲,这个答案对世界上大多数人来说基本上是无用的。【参考方案4】:

首先,我从未使用 OpenMP/MPI/OpenAcc/Cuda 进行编程。我知道的唯一 API 是 OpenCL,所以要小心我在下面所说的,它需要确认:p!

我更喜欢 OpenCL,但我认为 Cuda 和 OpenCL 在编译过程中没有太大区别:编译器将内联函数(即 C 代码中的内核)。 然后,在您的 OpenCL / Cuda 程序中,您可以在两个 GPU 任务之间进行 CPU 操作。

对于他们来说,有几种内存类型:

全局:cpu和gpu读/写 本地:仅由 gpu 读取/写入。 private : 一个简单内核的内存,其中存储了内核中声明的所有变量(仅限 gpu-core) constant : 用于常量定义的内存(仅限 gpu-core)

关于它还有很多话要说,但你可以很容易地在网上找到关于它的好指南。

然后因为他们的编译是内联的,你可以做一个 GPU/CPU 程序。你甚至可以在同一个程序中使用 OpenMP 和 OpenCL,我看不出有什么问题。

【讨论】:

CUDA 和 OpenCL 之间有很大的区别,前者将设备指令编译为机器码,而后者将设备指令作为字符串存储在生成的二进制文件中,仅在运行时将它们转换为特定于设备的机器码.除此之外,这意味着您在尝试运行 OpenCL 代码之前不会对其进行语法检查。

以上是关于openacc 与 openmp 和 mpi 的区别?的主要内容,如果未能解决你的问题,请参考以下文章

OpenACC + MPI Fortran 程序入门

共享内存的 MPI 与 openMP

OpenMP 和 MPI 混合程序

MPI+OpenACC编程中的GPU间通信

在 OpenCL 上使用 OpenACC?

在混合 MPI/OpenMP 中进行 MPI 调用的线程