OpenMP能在GPU上使用吗?

33

我在网上搜索了很多,但是对这个话题仍然感到非常困惑。有人能更清楚地解释一下吗?我来自航空航天工程背景(不是计算机科学),所以当我在网上阅读关于OpenMP/CUDA等多线程的内容时,我并不真正理解其中的大部分。

我目前正在尝试将用FORTRAN编写的内部CFD软件并行化。以下是我的疑问:

  1. OpenMP使用多个CPU线程共享工作负载。它可以被用来让GPU也参与工作吗?

  2. 我看过OpenACC的介绍。它和OpenMP相似吗(易于使用)?

我也看过CUDA和核函数,但我没有太多并行编程经验,也不知道核函数是什么。

  1. 是否有一种易于使用且可移植的方式来与GPU分享我的工作负载,适用于FORTRAN(如果OpenMP无法实现这一点,并且OpenACC不可移植)?

你能给我一个“白痴”式的答案吗?


我建议看一下OpenCL,因为它是在CPU和GPU上执行相同代码的简单方法。内核是可执行代码的基本单位,就像C函数一样,可以是数据并行或任务并行的。也存在Fortran到OpenCL的绑定。可以查看AMD的OpenCL介绍系列:https://www.youtube.com/watch?v=ecYIsu83c0I&list=PL3B46A983A7382FA6 - sled
3
搜索“OpenMP加速器”一词。在OpenMP 4.0中引入了加速器(其中GPU是一种类型)。 - High Performance Mark
随着即将发布的GCC 5编译器,现在已经支持了OpenMP 4.0和OpenACC计算卸载到加速器的基础设施支持。对于那些愿意尝试最新实验代码的人来说,如果你有NVIDIA GPU或支持的Intel Xeon Phi MIC卡,那么你可以开始涉足其中。 - Z boson
4个回答

15

是的。OpenMP 4目标结构设计支持广泛的加速器。支持NVIDIA GPU的编译器包括GCC 7+(参见12,后者尚未更新以反映OpenMP 4 GPU支持)、Clang(参见345)和Cray。Intel GPU的编译器支持可在Intel C/C++编译器中获得(例如,请参见6)。

IBM开发的适用于NVIDIA GPU的OpenMP 4+ Clang/LLVM实现可从https://github.com/clang-ykt获取。构建步骤在"OpenMP compiler for CORAL/OpenPower Heterogeneous Systems"中提供。
Cray编译器支持面向NVIDIA GPU的OpenMP目标。来自Cray Fortran Reference Manual (8.5)

支持面向NVIDIA GPU或当前CPU目标的OpenMP 4.5目标指令。必须加载适当的加速器目标模块才能使用目标指令。

Intel编译器支持C/C++的Intel Gen图形OpenMP目标,但不支持Fortran。此外,不支持teamsdistribute子句,因为它们不是必要的/适当的。以下是一个简单的示例,展示了不同环境中OpenMP目标特性的工作方式。
void vadd2(int n, float * a, float * b, float * c)
{
    #pragma omp target map(to:n,a[0:n],b[0:n]) map(from:c[0:n])
#if defined(__INTEL_COMPILER) && defined(__INTEL_OFFLOAD)
    #pragma omp parallel for simd
#else
    #pragma omp teams distribute parallel for simd
#endif
    for(int i = 0; i < n; i++)
        c[i] = a[i] + b[i];
}

Intel和GCC的编译器选项如下所示。我没有为NVIDIA GPU设置GCC,但您可以查看适当的-foffload选项的documentation
$ icc -std=c99 -qopenmp -qopenmp-offload=gfx -c vadd2.c && echo "SUCCESS" || echo "FAIL"
SUCCESS
$ gcc-7 -fopenmp -c vadd2.c && echo "SUCCESS" || echo "FAIL"
SUCCESS

1
问题特别要求使用Fortran语言。 - Vladimir F Героям слава
2
IBM正在开发两个OpenMP编译器。其中一个是Clang/LLVM编译器,另一个是XL编译器。对于Fortran语言,XL Fortran编译器支持大量的OpenMP 4.5卸载到NVIDIA GPU的子集,从版本15.1.5开始。今年和明年将添加更多功能,旨在在2018年实现完全支持。如果您使用POWER,可以加入测试计划以获取最新功能的访问权限。 - Rafik Zurob
@Jeff 可能是CUDA Fortran。无论如何,在我的阅读中,问题清楚地询问了OpenMP在Fortran加速器中的适用性。他谈到了一个Fortran代码(他应该完全重写成C++吗?),而且问题只有[标签:fortran]标签。 - Vladimir F Героям слава
混合语言编程越来越普遍,特别是在加速器的背景下。我正在处理一个超过400万行Fortran代码的项目(NWChem),但有人使用CUDA C进行了封装,因为那时候这是唯一可以使用NVIDIA硬件的方法(大约在2010年)。我对你的回答感到困惑,因为它提到了Intel编译器的C/C++特性作为证据,说明OpenMP 4.5编译器可以针对除NVIDIA之外的GPU硬件进行目标定位,而不是因为我认为这是OP想要使用的。 - Jeff Hammond
2
这是一个非常有帮助的答案。谢谢!在 CPU 上,simd 子句通常不是很有用,但在 GPU 上它似乎会产生很大的差异(使用 GCC)。请参见 此答案 的末尾。 - Z boson
显示剩余2条评论

9
  1. OpenMP 4.0标准包括对加速器(GPU、DSP、Xeon Phi等)的支持,但我不知道是否存在针对GPU的OpenMP 4.0标准实现,只有早期经验

  2. OpenACC确实类似于OpenMP且易于使用。优秀的OpenACC教程:part 1part 2

不幸的是,我认为目前至少没有CPU和GPU的可移植解决方案(除了OpenCL,但与OpenMP和OpenACC相比太低级了)。

如果您需要便携式的解决方案,可以考虑使用Intel Xeon Phi加速器代替GPU。Intel Fortran(和C/C++)编译器包括对CPU和Xeon Phi的OpenMP支持。
此外,要创建真正便携的解决方案,仅使用合适的并行技术是不够的。您必须修改程序以提供足够的并行级别。请参阅“Structured Parallel Programming”或类似书籍,了解可能的方法示例。

什么更好?在CPU还是GPU上运行程序的计算密集部分?当然这取决于具体的硬件,但一般来说呢? - André Almeida
一般来说,最好在GPU(或其他加速器,如Xeon Phi或FPGA)上运行计算密集型部分。现代加速器的性能至少比CPU性能高5倍。 - Andrey Sozykin

5
除了上面提到的其他平台上的支持,IBM正在为两个OpenMP 4.5编译器做出贡献:一个是开源的Clang/LLVM编译器,另一个是IBM的XL编译器。这两个编译器共享相同的辅助OpenMP卸载库,但在GPU的编译器代码生成和优化方面有所不同。对于Fortran语言,从版本15.1.5(对于XL C/C++来说是版本13.1.5)开始,XL Fortran编译器支持大量的OpenMP 4.5卸载到NVIDIA GPU中。今年和明年将添加更多功能,旨在在2018年完全支持。如果您使用POWER,则可以加入XL编译器测试计划,以获得我们最新的Fortran和C/C++的OpenMP卸载功能。

2
前面的回答已经涵盖了大部分内容,但是由于你提到需要给GPU一些工作,你可能想要看一下异构计算框架(CPU + GPU同时运行)如StarPU
由于StarPU只适用于C/C++,所以你可以使用ForOpenCL进行Fortran编程。
在任何情况下,你必须考虑性能和便利之间的权衡。

1
你注意到Fortran标签了吗? - Vladimir F Героям слава
StarPU 看起来很酷,但如果我没看错的话,它只适用于 C 语言。 - André Almeida
这个回答甚至没有试图回答问题。 - Jeff Hammond

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接