openacc vs openmp& mpi差异?

时间:2013-10-21 12:39:47

标签: cuda opencl mpi openmp openacc

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

4 个答案:

答案 0 :(得分:29)

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”示例中,主线程将输出所涉及线程的数量,而每个线程将从thread = xxx 打印 Hello World。

OpenACC是一组编译器指令,用于指定由连接加速器作为GPU加速的C / C ++或Fortran代码的部分。它遵循几乎相同的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

答案 1 :(得分: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的Exammple,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缓冲区的问题。

答案 2 :(得分:0)

了解共享和分布式范例,您可以在两个级别课程中更详细地回答您的问题, 如果您真的感兴趣,我建议您参加TACC(德克萨斯高级计算中心)夏季培训 动手学习

答案 3 :(得分:-1)

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

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

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

  • global:由cpu和gpu读/写
  • local:仅由gpu读/写。
  • private:存储内核中声明的所有变量的简单核心的内存(仅限gpu-core)
  • 常量:用于常量定义的内存(仅限gpu-core)

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

然后,由于他们的编译是内联的,您可以执行GPU / CPU程序。你甚至可以在同一个程序中使用OpenMP和OpenCL,我也没有看到任何问题。