写点什么

英伟达是如何做 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

2022-06-30 18:005321

评论 1 条评论

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

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

论监控中事件管理的艺术

穿过生命散发芬芳

事件管理 9月月更

活动报名| MongoDB 核心功能及其原理分析

MongoDB中文社区

mongodb

住宅代理IP在网络攻击中的作用

郑州埃文科技

代理IP 安全检测 撞库攻击

PSYNC 命令的实现

急需上岸的小谢

9月月更

PhotoView——支持图片缩放、平移、旋转的一个优雅的三方组件

OpenHarmony开发者

Open Harmony

跨链自动化中心 OAK Network,构建安全高效 Web3 基础设施

One Block Community

Substrate defi 跨链 区块链、

编译器优化:何为别名分析

华为云开发者联盟

开发 编译器 企业号九月金秋榜

阿里云视觉智能开放平台离线人脸识别SDK开启邀测啦

夏夜许游

人工智能 AI 人脸识别 离线包

送你5个MindSpore算子使用经验

华为云开发者联盟

人工智能 算子 企业号九月金秋榜

压测平台在全链路大促压测中的实践

得物技术

中间件 全链路压测 QPS 企业号九月金秋榜

荣耀帐号服务,让用户获取变得更简单

荣耀开发者服务平台

手机 物联网 安卓 移动开发 honor

【微信小程序】常用组件及基本使用详解

陈橘又青

小程序开发 9月月更

2022-09微软漏洞通告

火绒安全

microsoft 安全 终端安全 安全漏洞

iofod - Echart 图表全支持

iofod jude

Java 前端 低代码

TiDB部署----openEuler2203/2003 单机部署TiDB 6.1.1

TiDB 社区干货传送门

安装 & 部署

Pipy + Sentinel 实现 Redis 的高可用

Flomesh

Service Mesh 服务网格

资源使用率提高25%,成本降低90%,云函数是怎么做到的?

最新动态

mysql 查询执行过程

急需上岸的小谢

9月月更

TiDB分布式事务—写写冲突

TiDB 社区干货传送门

故障排查/诊断

依据TIdb执行计划的sql调优案例分享

TiDB 社区干货传送门

性能调优 管理与运维 HTAP 场景实践 大数据场景实践

TiDB生命周期

TiDB 社区干货传送门

实践案例 集群管理 管理与运维 数据库架构设计

Redis复制的实现

急需上岸的小谢

9月月更

MODBUS RTU 485 协议简要说明

矜辰所致

Modbus RS485 9月月更

力扣151 - 反转字符串中的单词【双指针与字符串的火花】

Fire_Shield

双指针 LeetCode 9月月更

一招教你如何高效批量导入与更新数据

华为云开发者联盟

数据库 sql 后端 企业号九月金秋榜

【死磕JVM】用Arthas排查JVM内存 真爽!我从小用到大

Java快了!

数据库发展史2--数据仓库

数据库 数据仓库 叶正盛 玖章

FreeRTOS记录(十、FreeRTOS实现带 I2C 通讯的 ModbusRTU 协议从机实例)

矜辰所致

FreeRTOS 9月月更 ModbusRTU

一步步搞懂MySQL元数据锁(MDL)

京东科技开发者

MySQL 数据库 元数据 数据库锁 mdl

奇点云数据云平台发布DataSimba R3.8长期支持版

奇点云

奇点云

实操指南:如何为 SAST 工具设置误报基准?

SEAL安全

应用安全 静态应用安全测试 SAST 应用安全测试 软件供应链安全

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