由于在读ASPLOS 13` GPUfs这篇文章,其中提到很多GPU特点,查了些资料,在这里简单总结一下。
GPU特点
1. 高吞吐量
2. 拥有数百个硬件处理单元,性能达到1Tflops
3. 每个处理单元深度多线程,即使有的线程被stall了,GPU还能够继续正常执行。
4. 高memory带宽
GPU发展和现状
1. GPU原来就是为了加速3D渲染的,后来被拿过来做计算。
2. 现在GPU可以支持通用的指令,可以用传统的C和C++,还有Fortran来编程。
3. 现在单个高端GPU的性能已经达到了传统多核CPU集群的性能
4. 有的应用通过GPU加速相比传统的多核CPU来说可以达到100X的加速。对某些特定应用来说GPU还是更适合的。
GPU编程模型
1. 在GPU中,工作的分配是通过在调度空间上并行地应用或者映射一个函数(或者叫做kernel)。举例来说,一个矩阵中的每一个点就是调度空间。
2. kernel就是描述在一个线程在调度空间中的每一个点要完成的工作。在调度空间中,每一个点都要启动一个线程。
3. 由于GPU是在单个PCI-e卡上的协处理器,数据必须通过显式地从系统内存拷贝到GPU板上内存。
4. GPU是以SIMD的多个group的形式组织的。在每一个SIMD的group(或者叫warp,在NIVIDA CUDA编程中为32个线程)中,所有的线程在lockstep中执行相同的指令。这样的在lockstep中执行相同指令的多个线程就叫做warp,虽然分支是被允许的,但是如果同一个warp中的线程出现不同的执行路径,会带来一些性能开销。
4. 对于memory-bound的应用来说,可能的话,同一个warp中的所有线程应当访问相邻的数据元素,同一个warp中相邻的线程应当访问相邻的数据元素。这可能要对数据布局和数据访问模式进行重新安排。
5. GPU有多个内存空间可用于开发数据访问模式。除了golbal memory以外,还有constant memory(read-only, cached),,texture memory(read-only, cached, optimized for neighboring regions of an array)和per-block shared memory(a fast memory space within each warp processor, managed explicitly by the programmer).
6. GPU编程有两个主要平台,一个是OpenCL,一个编程方式类似OpenGL的产业标准,还有另一个是为了C/C++ Fortran的CUDA,在NVIDIA的GPU上编程。
7. OpenCL/CUDA编译器并不是把C代码转换成CUDA代码,编程人员最主要的工作还是选择算法和数据结构。例如在GPU上,基数排序和归并排序要比堆排序和快速排序好。Some programming effort is also required to write the necessary CUDA kernel(s) as well as to add code to transfer data to the GPU,launch the kernel(s), and then read back the results from the GPU.
什么应用适合GPU
1. 内核中有豪多并行线程的应用
2. 对于线程间的数据交换都发生在kernel调度空间中的相邻线程之间的应用,因为这样就可以用到per-block shared memory.
3. 数据并行的应用,多个线程做相似工作,循环是数据并行的主要来源。
4. 那些能得到很好的天然硬件支持的应用,如倒数和反平方根,不过在编程中要打开"fastmath"选项,确保使用硬件支持功能。
5. 需要对每个数据元素做大量的计算,或者能够充分利用宽内存接口(wide memory interface这里有疑问)
6. 做同步操作较少的应用。
什么应用不适合GPU
1. 并行度小的应用,如需要的线程数小于100个,那么使用GPU加速效果不明显
2. 不规则的任务并行---尽管应用需要很多线程,但是这些线程都做不同的工作,那么GPU不能得到有效的利用。不过这也依赖于具体工作,多久对线程调度一次,加速的可能仍然存在。
3. 频繁的全局同步,这要求全局的barrier,带来很大性能开销。
4. 在线程之间,会出现随机的点对点同步的应用。GPU对这个的支持不好,通常需要在每次同步的时候做一个全局barrier,如果要利用GPU,最好重构算法避免出现这个问题。
5. 要求计算量(相比于数据传输量)少的应用。尽管在CPU+GPU计算结构中,GPU可以带来计算性能的提升,但是这些提升都被向GPU传输数据所消耗的实践覆盖了。举个例子,对于两个向量求和运算,如果非常大的向量的话,一般都选择在CPU上算,否则传输到GPU上的时间开销很大。
-
Other points to note:
- The GPU memory consistency model is relaxed (i.e. not sequentially consistent). A fast hardware barrier within a warp processor allows threads on a single warp processor to share data efficiently, especially if using the per-block shared memory. However, a global fence is required before one warp processor can safely use results from another warp processor.
- Peak computational throughput is achieved when all threads have roughly equal execution time. A thread block cannot complete and release the hardware for the next chunk of work until all threads in the thread block are done.
- Peak memory bandwidth is achieved when threads in a warp access neighboring regions of data. This is important because memory bandwidth can be a bottleneck for applications that do very small amounts of work per data element.
- For some examples of CUDA programs, see the Rodinia or CUDA Zone websites. An analysis of potential speedups and performance optimization considerations for a diverse set of application types can be found in this JPDC paper.
- For other programming tips, see the NVIDIA CUDA and OpenCL websites.
When is a GPU preferable to other ways of parallelizing (e.g. a cluster)?
- If you do not yet have a cluster: the cost of buying a GPU (or even, if necessary, a new PC to host a high-end GPU) is an order of magnitudelower than the cost of building a cluster. Setup, maintenance, and upgrade costs are also drasticallylower.
- A GPU system can be deployed at each user's desktop or benchtop.
- A cluster can be constructed with a GPU at each node.