原文:Is OpenACC The Best Thing To Happen To OpenMP?

作者:/nextplatform

翻译/编辑:GPU世界编辑部


在高性能计算领域,像其它领域的IT部门一样,对于技术人员来说,编程工具和编程模型的选择是一个非常个人的事。 如果要引起一场HPC程序员的争论,莫过于讨论OpenACC和OpenMP——这是两种解决并行计算问题的方法。

一般来讲,大家都会谈这两种技术时而竞争,时而互补。在The Next Platform网站上就有一场这样的对话。对话的双方就是OpenACC技术主席Michael Wolfe和OpenACC董事长Duncan Poole。Michael Wolfe也是编译器供应商Portland Group的技术领头人。PGI在2013年7月被英伟达收购。而Duncan Poole也是英伟达合作伙伴联盟负责人。

OpenACC是开放加速器(Open Accelerators)的简称,是由Cray、PGI、英伟达、早在2011年11月发起成立的一种编程标准。所有的创始人都有自己的编译器,都希望通过共同努力,创建一套标准,可以把指示语句放在Fortran,C和c++应用程序里,来帮助编译器找出并行部分的代码,放到加速器,比如GPU上,从而加快这些应用程序。 OpenACC的想法是,这些编译器指示语句可以在多核cpu以及各种各样的加速器上使用,不仅仅是Nvidia gpu,还包括许多核心处理器,比如Intel的Xeon Phi。有了OpenACC指示语句,编译器可以并行化代码,还可以进行CPU和GPU之间的数据移动。而重要的是,添加到代码中的指示语句是跨越许多架构,如果底层硬件变化,代码只需要重新编译就可以适应新的硬件平台。

Poole解释说无论是英伟达Tesla卡的CUDA编程环境,还是AMD的卡和DSP以及FPGA加速器们所使用的OpenCL框架,都免不了会引入繁琐冗余的并行计算和数据移动代码。而OpenACC的另一宗旨就是,让你能避免它们。在Poole展示的一份范例代码中,用CUDA C并行的出来的代码(量)大约比OpenACC多50%,而用OpenCL的甚至是OpenACC的3倍多。不过Poole也承认,也有(少数)情况,OpenACC处理并行计算和数据移动的时候,代码量跟OpenCL差不多。这些情况都可能发生。但是OpenACC重点在,能让编译器能自动处理掉这些,从而省掉繁琐冗余的(手工)并行计算和数据移动代码。

“坦白的讲,OpenACC所省掉的那些重复代码,基本上就是程序员写(CUDA和OpenCL)时候所需的平台和设备初始化代码,这些都被OpenACC自动(隐式)处理了。”Wolfe这样解释。“所以说CUDA和OpenCL总是在kernel代码之外有额外的工作需要做的。你每次不仅仅需要写kernel的代码, 你还需要去写上面这些初始化历程, 你还需要写代码去启动kernel。这些额外的代码开销大约在50% ~ 150%之间。”

Portland Group的编译器(缩写为PGI)现在支持将OpenACC指示语句用于多核cpu,并且无论系统上有没有GPU都可以并行化。 PGI同样正准备为Power8处理器+NV GPU协处理器的组合提供支持,而已经为即将到来的"Knights Landing"众核Xeon Phi处理器提供了指示语句支持. 所支持的后者需工作于独立启动模式, 这这种模式下,Knights Landing处理器如同一个普通的72核心的CPU, 加双层次的内存架构 --- wolfe表示他不相信有人能将Knights landing当做协处理器用。

编译器制造商PathScale,也支持将OpenACC指示语句用于ThunderX ARM服务器和Cavium网络。PGI和PathScale也支持AMD独立显卡芯片和AMD apu。 PathScale还初步支持ARM处理器和“开普勒”家族GPU加速器的组合,最常见的测试配置是一个ARM芯片和一个Tesla K20。PathScale也初步支持IBM的Power8处理器和开普勒Nvidia加速器组合。 

两年多前,Mentor Graphics加入了OpenACC社区,从那时候起,他们做了很多工作将OpenACC指示语句放在开源GNU编译器集,在SC15之前,该公司和GCC社区一起工作将更多的OpenACC指示语句用于编译器堆栈。 Poole说,它将支持Power8 + GPU的组合。然后Poole又加了句,他本人不是很确切知道当前的每个进展。(这对于开源软件来说很自然的,因为人们总是可以自行决定做什么)。IBM自家的XL C/C++编译器已经能抓取需要加速的并行代码片段,交给插入的Tesla加速器进行加速。但依然不是很清楚是否IBM能支持OpenACC指示语句。(考虑到IBM没有在OpenACC支持列表上的事实,这可能不会有支持的。但是又考虑到IBM如此强烈的想销售Power + Tesla组合的系统,如果不支持,又有点说不过来)

这只是一个开始,Wolf表示,有趣的是许多DSP和FPGA协处理器实际上有嵌入ARM cpu。 同时Wolf也说DSP前途无量,但是FPGA不尽然。 “有时你可以考虑将DSP做成附加的(计算)设备,”沃尔夫说。“我们每年都会接洽FPGA制造商,问我们什么时候去支持他们。 FPGA是一个完全不同的领域。 代码构建过程需要数小时,而不是几分钟,而你如果只用了几小时,而不是几天时间,就已经算幸运了。这上的代码会被FPGA的可用门数限制,而不是你的代码行数,所以你不能将一个完整的程序放到FPGA上,你顶多只能在上面实现一个特定的算法。你需要让你的算法使用大量的IO引脚,只有这样你才能生成较好的代码,否则你会得到非常糟糕的综合结果。不使用很多很多的用户IO引脚将导致综合器付出非常高的惩罚代价。 没有中间路线, 没有市场,没有希望。 顶多可以用来做研究性项目,而不是做产品”

不可否认,很多人在讨论FPGA加速,英特尔付167亿美元买FPGA制造商 Altera,产生了无限的遐想,很可能,激烈的辩论就像我们在讨论OpenACC和 OpenMP(另一个早于OpenACC的并行化方法) 。将来如果有一天,FPGA上的硬件编程,变得和人们心想的那样简单,将是一件喜闻乐见的好事。这将也将是对业界的一大利好。但更可能的是,在将来编程FPGA依然困难。在当前,既然有(本文说的这种CPU+GPU的混合系统)这种能真正全面编程,能真正容易编程的硬件存在,谁又何不更倾向选择它呢。

 当然,OpenACC工作并不局限于编译器制造商。 世界上有超过10000个程序员熟悉OpenACC,还有很多是供应商社区以外的正式项目。

德累斯顿技术大学所做的工作是将OpenACC支持放到代码调优软件,Allinea和Rogue Wave软件已经在他们的除错软件里支持OpenACC。 很多国家实验室和学术机构都在做这方面的努力,包括橡树岭国家实验室的OpenARC,筑波大学理化学研究所的OMNI,休斯顿大学的OpenUH,还有特拉华大学和路易斯安那州立大学的RoseACC项目。Nvidia也将PGI编译器、Nvidia Profiler和代码示例打包成OpenACC工具箱免费提供给教育单位。

在过去的5年里,OpenACC发展了三个版本,功能不断完善: 

至于未来,OpenACC社区正在开发一个新的功能,叫深复制。这是一个处理在系统里跨CPU和GPU上嵌套式动态数据结构的方式。 基本上,有时你想将整个结构从一个设备转移到另一个设备,包括所有所依赖的数据结构。 OpenACC社区,现正在为基础计算设备的层次化内存结构做准备。例如Intel的Knights Landing的Xeon Phi, 以及,将来的AMD和NV的GPU加速器。它们都具有两种形式的内存,一种是高带宽的加速器上的主内存,而另外一种则很可能利用系统内存,或者其他的非易失性存储器(例如3D XPoint)。OpenACC将要必须能够处理这点。同样的,对于跨CPU和GPU加速器启用的虚拟内存,OpenACC也同样需要能处理这点。

如果继续看的更远,将来一个系统中会有多种设备。我们可以预见将来应用程序在运行在部分CPU核心上的同时,也会将部分代码放到一堆混合的加速器上运行。OpenACC会在将来为这种程序的加速方式寻找更佳的支持方式。从这种情形上看,混合系统里将是CPU负责串行加速,而系统内部的网络化和集群化的GPU们,将负责大部分的并行处理任务。所以为这些不同的设备们提供更通用,或者某种程度上同样的处理方式,将变的很必要。这种支持将更有必要,特别是在将来当系统中同时存在有, GPU, DSP和FPGA的时候。(但NV可能很大程度上并不信任FPGA.。。)

对于选择OpenACC还是OpenMP,Poole说他是两个社区的成员,有很多人也都同时在这两个阵营。他的建议是现在编程和并行方法都是有价值的,不会浪费。Wolfe分享了下列的表格,来对比OpenACC2.5和OpenMP4.0。

“真正的问题是到底是OpenACC还是OpenMP可以解决用户的问题,”Wolfe解释说。 “对程序员来说,OpenMP更富有控制力,并且比OpenACC有更多的特性,但是我们并不为这个感到抱歉。OpenACC针对的是大规模的并行,而OpenMP则针对一些情形下不能大规模的并行情况---像是任务并行这种更普通的并行。虽然OpenMP具有更多的同步原语,但如果从大规模并行的角度上说,用更多的同步原语只会减慢你的程序。而重要的差异是是性能可移植性。”

Wolfe说,之所以出现这种情况,是因为OpenACC使用描述性的指示语句代码,告诉编译器如何并行化数据和相应的代码。

“例如对于一个循环,分别OpenACC和OpenMP指示语句的情况下,OpenACC会理解成将循环进行并行化,并要在你所拥有的硬件上运行的尽可能快。而OpenMP则理解成,为你生成一些并行的线程来拆分和执行循环。哪怕你的机器上具有SIMD并行能力,它也根本不会考虑利用它,除非你手工写明了如何去做。OpenMP只是提供了一套手工机制,可看成一种从源代码生成源代码的预处理器 --- 它更多的是由程序员去考虑和主导做什么,而不是自动做什么。这种机制很有力,但同时也是缺点,和OpenACC所提供的机制完全是两回事。通过OpenMP手工为一种硬件编程和优化固然可以提供性能,但当你需要在不同的硬件上,例如从多核的X86上, 到Knights Landing上,再到多核的ARM上,和Power+GPU的混合系统上,运行你的同样的程序的时候,同时保持性能的可移植性的时候,问题就来了。这些硬件具有完全不同的并行状况,SIMD并行能力、核心数量、内存的共享使用和层次结构,这些完全不同的东西影响你如何手工生成代码。

所以你需要一种能提供从同一份源代码中,生成映对各种目标硬件的优质代码的灵活机制。而这种就是我们认为OpenACC的独立优势所在。”

为了说明这一见,PGI展示了一个表格,比较了在多核CPU和CPU+GPU上运行相同代码的性能比较:

最终,OpenACC OpenMP社区已经一起工作,分享想法。Wolfe说,为OpenACC开发的一些特性在过去的五年里也用在了OpenMP,而且工作得很好。此外,Wolfe说,你可以在OpenMP里运行OpenACC,用多个主机线程来控制一个或多个GPU。

这引出了一个问题是否OpenACC和OpenMP应该合并。“最终是有这个想法,” Wolfe说。 “但是我们必须克服这种描述性指令和说明性指令的问题。”

不过Poole说“OpenACC对于OpenMP来说是个好事情。”因为它所带来的并行领域的创新正好推动了OpenMP。就好像Infiniband对于以太网,很好地推动了并行计算的发展!