本文专访嘉宾:崔慧敏,中科院计算所研究员。崔慧敏研究员关注异构环境下的编程和编译方向,具体的研究领域包括:异构编程模型,异构编译优化,数据中心编程与编译技术等。
关注 InfoQ “2021 年度技术盘点与展望”的朋友会发现,在编程语言部分,异构编程以及对多核算力的充分利用,已经成为编程语言领域众多研究和开发人员所关注的重点。
我们可以将异构编程受瞩目的原因归结为随着“云边端一体化”的发展,CPU、GPU 混合应用,构成了当下主要的算力基础设施。但从另一方面讲,与硬件的高度协同,本来也是编程语言的设计初衷。用中科院计算所研究员崔慧敏教授的话说,就是:
“编程语言设计,一直存在两个目标:一个就是让编程越来越容易;另外一个目标就是,在新的硬件架构出现后,编程语言要能够充分利用硬件特质,发挥其性能。”
但无论是 CPU 、GPU 还是 FPGA,其演进时间都不算短,为何在当下,我们对其仍然知之甚少呢?一方面是生态原因,因为整个开发者群体呈倒金字塔分布,大部分顶层的开发者不需要关注太多的底层细节,因而异构编程生态圈较小;另一方面则出在异构编程自己身上——它实在是太难了。
令开发者“为难”的异构编程
在早期,编程语言会通过引入新特性来支持多核算力,更充分地利用硬件性能。比如 C/C++引入了 OpenMP , 用于共享内存并行系统的多处理器程序设计,通过多线程的形式,榨干多核算力。
随着 GPU 更多地被部署在云计算、数据科学、AI 等领域,支持异构编程的框架开始出现。现在应用最广的是英伟达基于自家硬件推出的 CUDA 框架。
CUDA 无疑是开创性的,率先让 GPU 脱离了“显卡”的范畴,作为一枚强大的芯片,可以被程序员直接使用硬件访问接口进行编程。后来的 oneAPI、C++ AMP、OpenCL 都是不断围绕异构编程的概念做新的研发工具迭代。
但这样的发展态势,也给异构编程带来了麻烦:由于硬件本身仍是多元化的状态,大部分厂商更偏向围绕自己的硬件进行开发,没有也不愿分散太多资源用于支持其他厂商的硬件编程框架,导致异构编程的方案始终不够收敛。
到今天为止,异构编程的性能调优,始终是个相当大的挑战,它需要程序员不仅对软件研发有足够深入的了解,同时对各类型不同的硬件也有深刻认知。
崔慧敏教授以自己团队的日常工作为例,详细描述了异构编程的工作难度:
“团队那时在做一个关于超算的大型应用,其中一项工作是对泊松求解器进行研发和性能调优。按计划,我们首先要对这个应用进行拆分(很多 C 语言代码的模块化做得并不好),然后逐个步骤评估计算量,再将计算量最大的部分加载到加速核上执行。
当时我们发现其中两个步骤计算量最大,于是用 OpenCL 做了初步的实现,但测试完后,却发现性能非常差。我们分析了下原因,才发现所有的存储都在外部,而片上的高速存储没有用好。为了充分利用片上存储,我们调研、使用了循环分块、数据双缓冲等等机制,但应用之后,发现性能还是不够好。
没办法,只能继续分析。很快我们发现,虽然存储这里没问题了,但取数据的带宽没有充分利用起来。而超算芯片自有一套非常复杂的取数机制,为了做好这一块的性能调优,我们花费了大量的时间。
但调整了取数带宽,并没有完全解决问题,我们又发现,不规则的数据访问,导致分块也变得不合理……调整了分块,意味着向量化的策略也要重新调整……
最终,当我们把性能调整到一个可接受的水平,已经用掉了 10 个人月的时间(项目组共两人,每人占用 5-6 个月时间)。”
编译器的黄金时代,已经来了
尽管许多开发者在做程序跨硬件迁移时,其工作并不像崔教授基于超算平台做性能调优这样复杂,性能要求也不会这么高,但其难度仍是公认较高的。这背后的原因要追究到 CPU、GPU 乃至 FPGA 的硬件设计差异上。
CPU 有比较丰富的多元化指令,存在片上的多级缓存。要基于 CPU 进行程序调优,首先要想办法将程序划分为颗粒度更细的并行任务,并在负载均衡的情况下,分配到各个核上去执行,让每一组线程的流水线尽可能排满,让共享内存的访问锁尽可能的少。
而相比 CPU ,基于 GPU 的研发,需要将程序划分的比 CPU 并发性更高,颗粒度更细。划分完成后,还要考虑数据在存储上的摆放。同时,因为 GPU 擅长处理比较规整的计算,也需要我们更加理解这种较为规整的计算模型,甚至涉及部分数据结构的重新设计。同时,GPU 有很多浮点运算部件,需要找到足够多的浮点运算工作来充分利用其特性。
FPGA 与以上编程模式都非常不同。无论 CPU 还是 GPU ,本质上还是完成从软件到硬件的映射,但 FPGA 的关键在于精心设计生成线路,以充分利用硬件性能。早期的 FPGA 完全基于底层硬件描述语言编写,因此使研发工作变得非常困难。
因为硬件的巨大差异,导致异构编程通常只能选择中庸方案,在 CPU 上达到了极致性能,几乎一定会导致在 GPU、FPGA 上性能较差。
映射在开发者身上,就造成了迁移工作的困难。所以,另一类方案是基于支持异构编程的新型编程语言来做,C/C++ OpenMP 只是早期形态,更为典型的案例出现在国内 —— 华为在 2021 年推出的毕昇 C++,并发布了北冥多样计算性计算架构。据华为官方介绍,毕昇 C++是支持多样算力的通用编程语言,以 C++为基础,支持 SYCL 异构编程标准,以一种语言即可对鲲鹏、昇腾及业界主流算力进行编程。为了更好地配合毕昇 C++ ,华为同时发布了一个加速库,全称叫做“北冥融合加速库 2.0”为领域关键功能加速提供基于 API 的编程调用,进一步屏蔽硬件细节。
而北冥多样计算性计算架构主要面向多样性算力集群的软件开发需求,融合开发语言、编译器、调度器、开发框架、计算套件、开发工具链在内的整套多样性算力开发解决方案与生态。毕昇 C++、北冥融合加速库 2.0 都是计算架构的关键组件,相当于面向开发者的整体解决方案集成。
对毕昇 C++ 及北冥多样计算性计算架构而言,其采用的 SYCL 异构编程标准是业界一大创新和亮点。SYCL 异构编程标准是一种免版税,跨平台的抽象层,它允许使用标准 ISO C ++ 编写异构处理器的代码,并将应用程序的主机代码和内核代码包含在同一源文件中,也是业内最近关注度比较高的一套标准。许多科研人员正在基于 SYCL 进行性能方面的探索,但目前还未有来自学术界的确定性的答案。
而不管是毕昇 C++,还是北冥融合加速库, 其诞生一方面是为了缓解异构编程高度复杂的研发现状,一方面也反映了属于编译器的“黄金时代”正在到来,围绕编译器,在编程语言层面解决问题,正在成为异构编程的核心解决方案。
2017 年的两位图灵奖得主 John L. Hennessy 和 David A. Patterson 在年初的一篇报告中展望道:未来的十年将是计算机体系架构领域的“新的黄金十年”。同时,也有专家提到,编译器的“黄金十年”也到来了。
崔慧敏教授提到:“过去硬件发展得非常快,软件发展得自然也快,我们将那个时代形容为‘免费的午餐’。但在当下,‘免费的午餐’已经没有了。”
David A. Patterson 在报告中提到,通过语言的改善和编译器的优化,应用程序可以实现超过六万倍的性能提升。这就要求我们对编译器有非常深入的优化,以匹配当下的硬件环境。
当然,对编程语言及编译器的优化,不仅是个技术问题,也是个产品设计问题,它将永远在易用性和性能间摇摆,以取得最佳平衡。C++ AMP 曾因为易用性广受产业界、学术界欢迎,但也因为对底层操作的过度屏蔽,导致性能存在瓶颈,最终退出舞台。
同样的挑战,放在国内,对于毕昇 C++ 来说,也必将存在,而解决问题的主要途径很可能要归结在行业生态上。
生态决定未来发展
崔慧敏教授说:“早期基于 CPU 的编译器,大家对基础设施做了很好的抽象,与平台无关的部分考虑开源,其他部分考虑闭源。但现在大家更倾向自己做自己的,目前还没有对基础设施进行抽象。”
尤其是在当下硬件行业呈碎片化发展,除英特尔、英伟达的芯片外,鲲鹏、昇腾、倚天、Graviton……各类芯片百花齐放,若没有生态支撑,所谓的异构编程基础设施,很容易变成只属于某几类芯片的基础设施。开源也是个值得重点考虑的实现方式,RISC-V 的组织模式就起到了很好的示范作用。
这样从生态的视角来看,SYCL 作为开放的异构编程标准,就更有利于同样软件生态的建设,避免异构开发套件过度碎片化。
在国内,华为在毕昇 C++、北冥融合加速库方面的工作,对于整个产业而言是个很好的开始,代表着中国企业,开始在基础软件领域,全方位地向前迈进。但对比国外老牌厂商,能否实现弯道超车,则要仰仗于生态合力。
另外,崔慧敏教授认为,产业界和学术界的协同也值得引起重视。产业界有很好的工程化能力,有充足的需求和完善的平台;学术界则有很好的技术探索能力,一名学生天马行空的构想,也有可能成为未来产业界创新的解决方案。二者的充分结合,可以更好地推动行业发展。
在高校学生群体内的普及和教育,则是打造良性生态的另一个重要举措。而在学生群体里的成功推广,也是 CUDA 早期获得成功的重要原因。
在国内,华为也组建了“智能基座”产教融合协同育人基地,作为鲲鹏昇腾与高校师生的学习交流中心,其相关在线课程也包括高性能计算等内容。而同时面向高校学生的智能计算认证和鲲鹏应用开发者认证,早在 2019 年就已推出,开创了国内产学融合的新路径。
总体而言,产学研界的高度融合,再辅以一定的开源策略,或将决定异构编程生态的发展高度;而异构编程生态的发展,也将决定未来 IT 基础设施的服务能力。在国内已有企业率先迈开脚步的情况下,未来无疑充满想象。
评论