写点什么

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

评论 1 条评论

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

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

一份小盒饭的“深圳创新密码”

联营汇聚

直播预告|星策社区大咖说-第一期-蒙牛数智化转型访谈

星策开源社区

人工智能 转型 企业转型 智能化转型 蒙牛

OceanBase荣获OSCAR两项大奖,开源已成主流开发模式

OceanBase 数据库

“为场景找技术”:全球数字化转型的大同之道

脑极体

监控系统工作原理

穿过生命散发芬芳

监控系统 9月月更

数字化办公,企业OA软件技术该如何发力?

Speedoooo

小程序 数字化转型 软件技术 小程序容器 企业OA

昂贵的质量

光毅

项目管理 代码质量

史上最全的Java基础(针对面试)

自然

java; 9月月更

OpenTelemetry Go Metric SDK (Alpha) v0.32.0 发布

Grafana 爱好者

OpenTelemetry

Redis API——Set功能实践与性能测试【Go版】

FunTester

【微信小程序】你了解小程序开发吗?

陈橘又青

9月月更

设计模式总结(一):创建型模型

Studying_swz

设计模式 9月月更 创建型模型

赴一场深圳的线下沙龙|分布式数据库助力跨境企业降本增效

OceanBase 数据库

小六六读Effective记录

自然

java; 9月月更

【内存操作函数内功修炼】memcpy + memmove + memcmp + memset(四)

Albert Edison

C语言 9月月更 strcpy strncpy

低代码对接腾讯云-阿里云短信平台

葡萄城技术团队

低代码

小程序与工业互联网能够相辅相成的原因

Geek_99967b

小程序

开源?结缘!Towhee 开源社区与上海人工智能实验室 OpenDataLab 成为开源生态合作伙伴

Zilliz

人工智能 开源

【云原生 | 从零开始学Kubernetes】二、使用kubeadm搭建K8S集群

泡泡

Docker Kubernetes 云原生 容器编排 9月月更

不懂就问:“无人驾驶汽车革命”到底进行到哪一步了?

澳鹏Appen

人工智能 自动驾驶 无人驾驶 训练数据 数据训练

Java进阶(三十三)java基础-filter

No Silver Bullet

Java filter 9月月更

Javaweb核心之servlet详解

楠羽

Servlet 笔记 9月月更

分布式数据库技术之路未来如何发展?

OceanBase 数据库

史上最全的Java容器集合之入门

自然

java; 9月月更

【微信小程序】小程序的条件渲染

陈橘又青

9月月更

关联分析:实现全景化应用监控的基础

阿泽🧸

智能运维 9月月更

每日算法刷题Day15-0到n-1中缺失的数字、调整数组顺序、从尾到头打印链表、用两个栈实现队列

timerring

算法题 9月月更

NFTScan 与 Chamcha 在 NFT API 数据层面达成战略合作

NFT Research

eth API NFT 合作

出海嘉年华开发者说,模式复制、本地化创新和未来机会

融云 RongCloud

白皮书 程序猿 出海 圆桌论坛

救火不如防火 IoT平台技术构建智慧消防系统筑牢防火墙

AIRIOT

低代码 物联网 低代码,项目开发

KeeWiDB:兼容Redis协议,领跑NoSQL

腾讯云数据库

数据库 nosql 腾讯云 腾讯云数据库 KeeWiDB

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