【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

英伟达是如何做 GPU 编程的(一)

  • 2022-06-30
  • 本文字数:3999 字

    阅读完需:约 13 分钟

英伟达是如何做GPU编程的(一)

在这篇文章中,我将介绍最简单、最高效、最可移植的加速计算方式。即三种可以用于 GPU 编程的方式。


图1 对NVIDIA平台进行编程的三种方式


CUDA C++ 和Fortran是英伟达能够展示新硬件和软件创新的创新基础,在这里你可以调整你的应用程序以实现在 NVIDIA GPUs 上的最佳性能。许多开发人员认为,这就是英伟达期望每个人为 GPU 编程的方式。


相反,我们希望首次使用 NVIDIA 平台的开发人员能够使用标准的并行编程语言,如 ISO C++、ISO Fortran 和 Python。在这篇文章中,我将重点介绍一些使用这种方式进行并行编程的成功案例,以展示进入英伟达 CUDA 生态系统最有效的途径。


英伟达战略的基础是提供一套丰富且成熟的 SDK 和库,可以基于它们构建应用程序。 英伟达已经提供了高度优化的数学函数库,例如cuBLAScuSolvercuFFT;核心库,例如Thrustlibcu++;通信库,例如NCCLNVSHMEM,以及其他可以在其上构建应用程序的包和框架。


除此之外,英伟达还分层了三种不同的编程方式:


  • 标准语言并行开发,这是本文的主题

  • 平台专用语言,如 CUDA C++和 CUDA Fortran,以在 NVIDIA 平台上获得最佳性能

  • 编译器指令,通过启用增量性能优化来弥合这两种方式之间的差距每种方式都在性能、生产率和代码可移植性方面进行权衡。由于它们都可以互操作,所以你不必使用特定的模型,但可以根据需要混合使用任一或所有模型。


如果你是以使用标准编程语言中的并行来开始编写代码的,那么你可以使用 NVIDIA 平台或任何其他已经具有并行运行能力的基线代码平台。这就是为什么我们投入了十多年的时间来与标准语言委员会合作,采用特性来实现并行编程,而不需要额外的扩展或 API。标准语言并行开发是一股水涨船高的潮流,能让所有人都感到振奋。

ISO C++


在最近的编程趋势研究中,C++编程语言一直是顶级编程语言之一。它在科学计算方面的使用有了显著的增长。其标准模板库的丰富性使其成为一种用于新代码开发的高效语言,并且自 C++ 17 发布以来,它已支持并行编程的多个重要特性。


我已经看到一些应用程序在重构时摒弃了传统的 for 循环,转而采用这些 C++的并行算法。以下是其中一些的结果。

Lulesh


Lulesh 是劳伦斯利弗莫尔国家实验室( Lawrence Livermore National Laboratory,LLNL)的一个流体动力学迷你小应用程序,用 C++编写。这个迷你应用程序有多个版本,可用于评估不同的编程方式,包括代码质量和性能。我们与其开发人员一起合作,重写了他们现有的基于 OpenMP 的代码,以使用 C++并行算法。图 2 是仅显示了应用程序其中某个重要特性的示例。


图2 将Lulesh从OpenMP重构为ISO C++并行,可以得到更简单、更易于阅读、符合ISO标准并且可移植到所有支持ISO C++编译器的代码


左边的代码使用 OpenMP 跨 CPU 线程并行代码中的循环。为了同时维护代码的串行和并行版本,开发人员使用了 #ifdef 宏和编译器编译指令 pragma。导致的结果是会出现重复代码,并且在源代码中引入了额外的 API,OpenMP。


右边的代码是相同的例程,但是使用 C++ transform_reduce 算法重写了。由此生成的代码更紧凑、更不容易出错、更易于阅读且更易于维护。它还移除了对 OpenMP 的依赖项,转而依赖于 C++标准模板库,同时为所有平台维护了单一的源代码。该代码完全符合 ISO C++,能够由任何支持 C++ 17 的 C++编译器构建。事实证明,它也更快了!


图3 Lulesh的ISO C++版本比原始的OpenMP代码更快,可移植到多个编译器,并且可在CPU 和GPU之间进行移植


作为性能的基准,我们使用的 OpenMP 代码用 GCC 构建并运行在 AMD EPYC 7742 处理器的所有内核上。使用 NVIDIAnvc++编译器重新构建该基线代码,在 CPU 上基本可以获得相同的性能。


如果你使用同一版本的 GCC 来构建 ISO C++代码,并让其运行在相同的 CPU 上,那么性能将提高大约 50%,这是由于编译器各种改进开销,使其有机会更好地优化代码。


当使用 nvc++构建代码并在同一个 CPU 上运行时,性能能够提高 2 倍。这已经是一项激动人心的成就了,但除此之外,你可以构建相同的代码,只需将编译器选项更改为针对 NVIDIA GPU,而不是多核 CPU 的。现在,同样的代码在 NVIDIA A100 GPU 上运行,速度快了 13 倍多。与原始代码相比,使用严格的 ISO C++的代码,性能提高了 13.5 倍,并且能在 CPU 和 GPU 上并行运行。

STLBM


应用 C++标准并行的另一个例子是 STLBM,来自日内瓦大学的 Lattice-Boltzmann 求解器。Jonas Latt 教授在多个 GTC 会议中讨论了这个应用,展示了在没有依赖任何外部 SDK 的情况下,用 ISO C++编写的代码如何在多个编译器以及多个硬件平台上运行的,包括 NVIDIA GPU。相关的更多信息,请参见《GPU上的流体力学与C++并行算法:通过硬件无关的方式获取最先进的性能》和《使用C++标准并行将一个科学应用移植到GPU上


他的应用程序使用 GPU 实现了超过 12 倍的性能提升。值得注意的是,他的比较基准是一个默认情况下是并行的源代码,使用 C++ 17 标准模板库中的并行算法来表达应用程序中固有的并行性。


他将使用 ISO C++作为 GPU 编程的经验归类为“跨平台 CPU/GPU 编程的范式转换”。他的团队没有编写一个默认情况下是串行的应用程序,然后再添加并行性,而是编写了一个可以在任何他们希望的并行平台上运行的应用程序。


图4 STLBM能够在多核CPU节点和NVIDIA GPU上运行相同的源代码


英伟达在 C++并行性和并发性的持续开发方面投入了大量的资金,并为即将到来的 C++ 23 规范共同撰写了各种提案,以进一步提高编写“并行优先”(parallel-first)代码的能力。

ISO Fortran


Fortran 仍然是一种主要关注科学和高性能计算的语言。Fortran 最初是公式转换器(FORmula TRANslator),它为开发人员和编译器提供了各种优势,并且还拥有用于建模和仿真代码的庞大现有代码库。


Fortran 开始在 Fortran 2008 中添加支持并行编程的特性,在 Fortran 2018 中增强了这些能力,并在即将推出的版本(目前称为 Fortran 202X)中继续完善它们。与 ISO C++一样,英伟达一直在与其应用程序开发人员合作,在 Fortran 中使用标准语言的并行来现代化他们的应用程序,使其成为“并行优先”(parallel-first)。

计算化学


我的同事 Jeff Hammond 在他的“FortranCon2021:GPU上的标准Fortran及其在量子化学代码中的应用”会议介绍中,展示了一些使用 Fortran 在内核中执行do concurrent循环的有前景的结果,这些循环取自 NWChem 应用程序,以及另一个计算化学应用程序 GAMESS。


对于 NWChem,他隔离了多个执行张量收缩的性能关键循环,并使用多个编程模型来编写它们。在多核 CPU 上,这些张量收缩使用 OpenMP 来跨 CPU 内核进行线程处理。对于 GPU 来说,有一些版本可以使用 OpenACC、OpenMP 目标卸载,现在还可以使用 Fortran do concurrent 循环。


图 5 显示,在 NVIDIA GPU 上执行do concurrent循环的性能与 OpenACC 和 OpenMP 目标卸载的性能相同,但不需要在应用程序中包含这些额外的 API。这都是标准的 Fortran。


图5 使用多种编程模型内核的一系列NWChem应用程序的性能

高性能通量传输


在最近与 SC21 会议同期举行的指令加速器编程研讨会(WACCPD)上,来自Predictive Science Inc. 的一个开发团队展示了他们其中的一个重构代码的结果,这些代码之前使用 OpenACC 在 NVIDIA GPU 上运行,使用了 do concurrent 循环。


他们比较了使用 NVIDIA nvfortrangfortranifort 构建这个纯 ISO Fortran 应用程序的结果。他们得出的结论是,对于使用 nvfortran 编译器的应用程序,纯 Fortran 无需任何指令即可提供他们所需的性能。此外,该代码无需修改即可在 GPU 和多核 CPU 上并行运行。


这图6 使用nvfortran编译器的HipFT基准测试的性能结果


这篇论文获得了研讨会的最佳论文奖,尽管它根本不需要任何加速器编程指令。当被问及是否会在他们的其他应用程序中继续采用标准语言并行方式时,演讲者回答说,他们已经计划在公司的其他重要应用程序中采用这种方式。

带有 Legate 和 cuNumeric 的 Python


在过去的十年中,Python 语言的受欢迎程度急剧上升。它现在常用于机器学习、数据科学,甚至传统的建模和仿真应用。虽然 Python 与 C++和 Fortran 不同,它不是 ISO 标准的编程语言,但我们也在 Python 语言中实现了标准语言并行的精神。


在秋季 GTC’21 的主题演讲中,英伟达首席执行官黄仁勋(Jensen Huang)介绍了cuNumeric的 alpha 版本,这是一个以 NumPy 为模型的库,它能够实现我前面讨论的 ISO C++和 Fortran 类似的特性。 NumPy 包在 Python 开发中非常普遍,几乎可以肯定,任何用 Python 编写的 HPC 应用程序都会使用它。


cuNumeric包编写在一个名为Legate的包之上,它使 NumPy 应用程序不仅能够自动将工作扩展到 GPU 上,而且还能在跨大型集群中的 GPU 上自动扩展工作。 我已经看到了几个示例应用程序,它们只是简单地将代码中对 NumPy 的引用替换为对 cuNumeric 的引用,就可以将该应用程序稍微地扩展到 NVIDIA 内部集群 Selene 的完整大小,Selene 是世界上最快的 10 台超级计算机之一。


有关 cuNumeric 的更多信息,请参阅英伟达宣布推出的cuNumeric Public Alpha版,并观看 GTC 点播会议,Legate:扩展Python生态系统

结论


我希望这篇文章能够给你启发,使你明白 GPU 编程并不像你听说的那么难。如果你使用标准语言并行,甚至可能不需要做任何代码更改。


英伟达鼓励你以并行优先的方式编写应用程序,这样就永远不需要将应用程序“移植”到新平台,而标准语言并行是实现这一点的最佳方式,因为它只需要 ISO 标准语言。 这就是为什么我们继续投资于 ISO 编程语言,并为这些语言带来更多的并行和并发特性的原因。


总之,使用标准语言并行有以下好处:


  • 完全符合 ISO 语言标准,代码更易于移植

  • 代码更紧凑、更容易阅读、更不容易出错

  • 默认情况下代码是并行的,因此可以在更多平台上运行而无需修改


以下是来自 GTC’21 的一些演讲,它们可以为你提供更多关于这种并行编程方式的细节:



相关更多信息,请参阅以下资源:


  • 了解有关编译器支持的更多信息以及 HPC SDK 上的其他文章。

  • 免费下载HPC SDK软件


作者介绍


Jeff Larkin 是英伟达高性能计算(HPC)软件团队的首席 HPC 应用架构师。他对高性能计算并行编程模型的发展和采用充满热情。他曾是英伟达开发技术小组的成员,专门从事高性能计算应用的性能分析和优化。Jeff 还是 OpenACC 技术委员会的主席,他曾在 OpenACC 和 OpenMP 标准机构工作过。在加入英伟达之前,Jeff 曾在位于橡树岭国家实验室(Oak Ridge National Laboratory)的 Cray 超级计算卓越中心工作过。


原文链接:


https://developer.nvidia.com/blog/developing-accelerated-code-with-standard-language-parallelism

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2022-06-30 18:004131

评论 1 条评论

发布
用户头像
环境编译很麻烦?

2022-07-01 08:17
回复
没有更多了
发现更多内容

Android C++系列:NDK减少so库体积方法总结

轻口味

c++ android 4月月更

适合 Kubernetes 初学者的一些实战练习 (六)

Jerry Wang

Docker Kubernetes 云原生 Serverless Kubernetes 4月月更

PlatoFarm将DAO理念发扬光大,让DAO社区受益才能走得远

西柚子

RocketMQ—Producer(三)发送方式和消息类型

IT巅峰技术

Flutter 通过自定义路由拦截实现权限管理

岛上码农

flutter ios 移动端开发 安卓开发 4月月更

ECharts 饼图颜色设置教程 - 4 种方式设置饼图颜色

蒋川

eCharts

企业如何度量研发效能?

PingCode

架构实战营【模块二】作业

michael

架构实战营 「架构实战营」

展业四海,服务八方,明道云落地蜀陕豫鄂

明道云

王者荣耀商城异地多活架构设计

Geek_36cc7c

Linux驱动开发-编写OLED显示屏驱动

DS小龙哥

4月月更

去中心化云存储的前世今生 | 存储技术分享活动回顾

One Block Community

区块链 Substrate 去中心化存储 波卡

RocketMQ—Producer(四)消息发送流程

IT巅峰技术

元宇宙大热,是风口还是虎口

CECBC

游戏化与驱动力 —《游戏化实战》读后感

Bruce Talk

敏捷 随笔 Agile

自己动手写Docker系列 -- 5.4实现进入容器的namespace,exec命令

Docker Go 语言 4月月更

国内又一款效能度量工具发布,让研发效能真正可量化、可分析、可提升

PingCode

Spring如何解决循环依赖

IT巅峰技术

训练营作业-Module2:朋友圈高性能复杂度分析

Jadedev

架构训练营

微信朋友圈的高性能复杂度分析

高山觅流水

「架构实战营」

研发管理工具 PingCode 宣布正式支持敏捷开发、Kanban、瀑布开发管理

PingCode

首期Moonlight Builder Workshop | 如何在 Moonbeam 快速开发和部署 DApp

One Block Community

dapp SBUSUART Moonbeam 波卡生态 Scaffold-ETH

Twitter架构决策

俞凡

架构 大厂实践

生产环境Redis连接,长时间无响应被服务器断开问题

越长大越悲伤

redis TCP 连接 springboot

常用的高情商话术

williamcai

人生之道

williamcai

人生修炼

架构实战营 - 模块二作业

凯博无线

招聘 | Bifrost、Gear、Phala Network等多家波卡生态项目招聘区块链开发者

One Block Community

波卡生态 区块链招聘 bifrost gear Phala Network

PlatoFarm将DAO理念发扬光大,让DAO社区受益才能走得远

小哈区块

朋友圈架构设计

踩着太阳看日出

架构训练营

不断挖掘“区块链”更大潜能

CECBC

英伟达是如何做GPU编程的(一)_文化 & 方法_Jeff Larkin_InfoQ精选文章