CUDA C和C ++的说明

谁能给我一个关于CUDA C和C ++性质的很好的解释? 据我了解,CUDA应该是带有NVIDIA GPU库的C语言。 截至目前,CUDA C支持一些C ++function,但不支持其他function。

什么是NVIDIA的计划? 他们是否会在C上构建并添加与C ++相似的库(例如Thrust vs. STL)? 他们最终会支持所有的C ++吗? 在.cu文件中使用C ++标头是不是很糟糕?

CUDA C是一种具有C语法的编程语言。 从概念上讲,它与C完全不同。

它试图解决的问题是为多个处理器编写多个(类似的)指令流。

CUDA提供的不仅仅是单指令多数据(SIMD)矢量处理,而是数据流>>指令流,或者带来的好处要少得多。

CUDA提供了一些机制来实现这一点,并隐藏了一些复杂性。

CUDA没有针对多核x86等多种指令流进行优化。 CUDA不限于像x86向量指令那样的单个指令流,也不限于像x86向量指令这样的特定数据类型。

CUDA支持可以并行执行的“循环”。 这是它最关键的function。 CUDA系统将对“循环”的执行进行分区,并在一组相同的处理器上同时运行“循环”主体,同时提供正常顺序循环的一些错觉(特别是CUDA管理循环“索引”)。 开发人员需要了解GPU机器结构才能有效地编写“循环”,但几乎所有管理都由CUDA运行时处理。 效果是在一个’循环’的同时完成数百(甚至数千)个’循环’。

CUDA支持分支的外观。 只有运行与if测试匹配的代码的处理器才能处于活动状态,因此if测试的每个“分支”的处理器子集都将处于活动状态。 作为一个例子, if... else if ... else ... ,有三个分支。 每个处理器只执行一个分支,并且当if完成时,“重新同步”准备继续与其余处理器一起继续。 可能有些分支条件与任何处理器都不匹配。 因此不需要执行该分支(对于该示例,三个分支是最坏的情况)。 然后只按顺序执行一个或两个分支, if更快if完成整个分支。

没有“魔力”。 程序员必须意识到代码将在CUDA设备上运行,并有意识地为其编写代码。

CUDA不会使用旧的C / C ++代码,而是自动地在一系列处理器上运行计算。 CUDA可以按顺序编译和运行普通的C和大部分C ++,但是由于它将按顺序运行,并且比现代CPU更慢,因此很少(没有?)可以获得。 这意味着某些库中的代码(还)与CUDAfunction不匹配。 CUDA程序可以同时对多KB的位向量进行操作。 CUDA无法自动神奇地将现有的顺序C / C ++库代码转换为可以执行此操作的内容。

CUDA确实提供了一种相对简单的编写代码的方法,使用熟悉的C / C ++语法,添加了一些额外的概念,并生成将在一系列处理器上运行的代码。 它有可能提供超过10倍的加速比例,例如多核x86。

编辑 – 计划:我不适用于NVIDIA

为了获得最佳性能,CUDA在编译时需要信息。

因此,模板机制是最有用的,因为它为开发人员提供了一种在编译时说出来的方法,CUDA编译器可以使用它。 举一个简单的例子,如果在编译时将矩阵定义(实例化)为2D和4 x 8,那么CUDA编译器可以使用它来跨处理器组织程序。 如果该大小是动态的,并且在程序运行时发生更改,则编译器或运行时系统更难以完成高效的工作。

编辑:CUDA有类和function模板。 如果人们读到这篇文章说CUDA没有,我道歉。 我同意我不清楚。

我相信模板的CUDA GPU端实现并不完全是C ++。

用户哈里斯评论说我的回答是误导性的。 哈里斯为NVIDIA工作,所以我会等待建议。 希望这已经更清楚了。

在多个处理器之间有效处理的最困难的事情是动态分支许多备用路径,因为它有效地序列化了代码; 在最坏的情况下,一次只能执行一个处理器,这会浪费GPU的好处。 所以虚拟function似乎很难做得很好。

有一些非常聪明的整体程序分析工具可以推断出比开发人员可能理解的更多的类型信息。 现有工具可能推断出足以消除虚函数,因此将分支分析转移到编译时。 还有一些用于检测程序执行的技术,这些技术直接反馈到程序的重新编译中,这可能会达到更好的分支决策。

AFAIK(模反馈)CUDA编译器在这些领域尚不具备最新技术水平。

(恕我直言,对于任何对CUDA或支持OpenCL的系统感兴趣的人来说,研究它们并做一些实验值得花几天时间。我也认为,对于对这些领域感兴趣的人来说,值得努力尝试Haskell,看看Data Parallel Haskell )

CUDA是一个平台(架构,编程模型,汇编虚拟机,编译工具等),而不仅仅是一种编程语言。 CUDA C只是构建在这个平台上的众多语言系统之一(CUDA C,C ++,CUDA Fortran,PyCUDA等等)。

CUDA C ++

目前,CUDA C ++支持CUDA C编程指南附录D(“C / C ++语言支持”)中描述的C ++子集。

仅举几例:

  • __device__成员函数(包括构造函数和析构函数)
  • inheritance/派生类
  • 虚函数
  • 类和函数模板
  • 运算符和重载
  • 仿函数类

编辑:从CUDA 7.0开始,CUDA C ++在__device__代码中支持C ++ 11标准的大多数语言function(在GPU上运行的代码),包括auto ,lambda表达式,基于范围的for循环,初始化列表,静态断言等等。

实例和具体限制也在上面链接的相同附录中详述。 作为CUDA使用C ++的一个非常成熟的例子,我建议查看Thrust 。

未来的计划

(披露:我为NVIDIA工作。)

我无法明确未来的版本和时间,但我可以说明几乎每个CUDA版本都添加了额外的语言function以使CUDA C ++支持其当前(在我看来非常有用)状态的趋势。 我们计划在改进对C ++的支持方面继续这一趋势,但我们自然会优先考虑在大规模并行计算架构(GPU)上有用且高效的function。

许多人都没有意识到,CUDA实际上是两种新的编程语言,都源自C ++。 一种是编写在GPU上运行的代码,是C ++的一个子集。 它的function类似于HLSL(DirectX)或Cg(OpenGL),但具有更多function和与C ++的兼容性。 我不需要提及各种与GPGPU / SIMT /性能相关的问题。 另一种是所谓的“运行时API”,它几乎不是传统意义上的“API”。 Runtime API用于编写在主机CPU上运行的代码。 它是C ++的超集,使链接和启动GPU代码变得更加容易。 它需要NVCC预编译器,然后调用平台的C ++编译器。 相比之下,Driver API(和OpenCL)是一个纯粹的标准C库,使用起来要冗长得多(虽然提供的附加function很少)。

创建一种新的主​​机端编程语言是NVIDIA的一个大胆举措。 它使CUDA入门更容易,编写代码更优雅。 然而,真正的辉煌并没有将它作为一种新语言进行营销。

有时你会听到CUDA会是C和C ++,但我认为不是这样,因为这是不可能的。 从他们的编程指南中引用:

对于主机代码,nvcc支持主机c ++编译器支持的C ++ ISO / IEC 14882:2003规范的任何部分。

对于设备代码,nvcc支持D.1节中说明的function,但有一些限制在D.2节中描述; 它不支持运行时类型信息(RTTI),exception处理和C ++标准库。

正如我所看到的,它只涉及C ++,并且只支持C,这恰好出现在C和C ++的交集中。 所以最好把它想象成带有设备部分扩展而不是C的C ++。如果你习惯了C,那就避免了很多麻烦。

什么是NVIDIA的计划?

我认为总体趋势是CUDA和OpenCL被认为是许多应用程序的过低技术。 目前,Nvidia正在大力投资OpenACC ,大致可以将其描述为GPU的OpenMP。 它遵循声明性方法,并在更高的层次上解决GPU并行化的问题。 这是我对Nvidia计划的完全主观印象。