本笔记覆盖https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/的前言到第5章。

该指南面向读者:可流畅阅读C++代码,对Optimization一节的阅读还需要一定程度熟悉CUDA编程了。

对应用并行编程优化的方法论:

Assess:找到应用的性能瓶颈在哪

Parallelize:对性能瓶颈处使用任意的GPU并行库进行并行化

Optimize:多层级的优化措施

Deploy:一个原则是一次进行部分模块的并行化,让代码演进是渐进式进行,而不是发生革命性变化。

(名词解释:Host是CPU系统,Device是GPU系统)

Host和Device的不同:

  • 线程资源:Host上,执行流水线只能支持相对少量的并行线程。举例:带有2个32核CPU的服务器最大支持64个线程并行运行。而现代的NVIDIA GPU的一个多核处理器能支持2048个线程,而一个GPU可能能带有80以上的多核处理器。
  • 线程:GPU上的线程相对轻量化。
  • RAM:Host和Device分别拥有分离的物理内存。

决定把应用某一部分放在Device上运行考虑的因素:

  • Device适合的场景是很多的数据元素需要被并行处理,进而使用大量的并行线程去完成操作2,比如大数据集(矩阵……)的代数操作。
  • 使用CUDA时,数据需要从host传送到device上。这一步开销大,需要尽量避免。
    • 避免出现实际操作的开销和传送开销相近甚至更小的情况
    • 应让数据尽可能长地停留在Device端
  • 相邻的Device上的线程应访问相近的内存。

Strong Scaling:对固定问题规模,运行时间如何随着更多的处理器加入系统而被减少的度量方式。

Wake Scaling:运行时间如何随更多处理器加入系统而减少,总问题规模随处理器数量增加而增加。

Amdahl定律、Gustafson定律

达成并行优化的方式:

  • 用并行库(cuBLAS、cuFFT、Thrust等),直接用高级抽象的代码替代原来的接口调用,实现原本的功能(比如矩阵加,fft等),达成并行化
  • 并行编译器:一般是directive-based,比如给一个函数加个扩展的修饰,编译器看到这个修饰就知道要对这个函数做并行化处理
  • coding to expose parallelism(不知道怎么翻译……):cuda就属于这一类,比上两种更底层,自己去处理并行代码的执行细节