GPU 编程模型 (GPU Development Models)简述
▪ 在 GPU 中,工作的分配是通过在调度空间上并行地应用或者映射一 个函数(或者叫做 kernel)。举例来说,一个矩阵中的每一个点就 是调度空间。
▪ kernel 就是描述在一个线程在调度空间中的每一个点要完成的工 作。在调度空间中,每一个点都要启动一个线程。
▪ 由于 GPU 是在单个 PCI-e 卡上的协处理器,数据必须通过显式地从 系统内存拷贝到 GPU 板上内存。
▪ GPU 是以 SIMD 的多个 group 的形式组织的。在每一个 SIMD 的 group(或者叫 warp,在 NIVIDA CUDA 编程中为 32 个线程)中,所 有的线程在 lockstep 中执行相同的指令。这样的在 lockstep 中执行 相同指令的多个线程就叫做 warp,虽然分支是被允许的,但是如果 同一个 warp 中的线程出现不同的执行路径,会带来一些性能开销。
▪ 对于 memory-bound 的应用来说,可能的话,同一个 warp 中的所有 线程应当访问相邻的数据元素,同一个 warp 中相邻的线程应当访问 相邻的数据元素。这可能要对数据布局和数据访问模式进行重新安 排。
▪ GPU 有多个内存空间可用于开发数据访问模式。除了 global memory 以外,还有 constant memory(read-only, cached),texture memory(read-only, cached, optimized for neighboring regions of an array)和 per-block shared memory。
▪ GPU 编程有两个主要平台,一个是 OpenCL,一个编程方式类似 OpenGL 的产业标准,还有另一个是为了 C/C++ Fortran 的 CUDA, 两个平台都可以在 NVIDIA 的 GPU 上编程。
▪ OpenCL/CUDA 编译器并不是把 C 代码转换成 CUDA 代码,编程人员 最主要的工作还是选择算法和数据结构。例如在 GPU 上,基数排序 和归并排序要比堆排序和快速排序好。不过,在编写一些必要的CUDA 核函数、需要添加代码以使得程序向 GPU 传输数据或者启动 内核函数,然后从 GPU 读取结果时,都需要一些编程工作。
问题来源