您的位置:首页 > 其它

CUDA 学习(二)、使用GPU理解并行计算

2016-10-24 11:40 429 查看
一、并发性

       由于“易并行”不需要或者只需要少许线程间或线程块间通信,所以CUDA是很理想的并行求解平台。它用基于片上资源的、显式的通信原语来支持线程间通信。但是块间通信只有通过按顺序调用多个内核程序才能实现,而且内核间通信需要用到片外的全局内存。块间通信还可以通过对全局内存的原子操作实现,当然使用这样方法会受到一定的限制。

      CUDA将问题分解成线程块的网格,每块包含多个线程。快可以按任意顺序执行。不过在某个时间点上,只有一部分块处于执行中。一旦被调用到GUP包含的N个“流处理器簇(SM)”中的一个上执行,一个块必须从开始到结束。网格中的块可以被分配到任意一个有空闲槽的SM上。起初,可以采用“轮询调度”策略,以确保分配到每一个SM上的块数基本相同。对绝大多数内核程序而言,分块的数量应该是GPU中物理SM数量的八倍或更多倍。

     以一个军队比喻,假设有一支由士兵(线程)组成的部队(网格)。部队被分成若干个连(块),每个连队由一位连长来指挥。按照32名士兵一个班(一个线程束),连队又进一步分成若干个班,每个班由一个班长来指挥。

 


     要执行某个操作,总司令(内核程序/ 主机程序)必须提供操作名称及相应的数据。每个士兵(线程)只处理分配给他的问题中的一小块。在连长(负责一个块)或班长(负责一个束)的控制下,束与束之间的线程或者一个束内部的线程之间,要经常地交换数据。但是,连队(块)之间的协同就得由总司令(内核函数/ 主机程序)来控制。

二、局部性

       对于GPU程序设计,程序员必须处理局部性。对于一个给定的工作,他需要事先思考需要哪些工具或零件(即存储地址或数据结构),然后一次性地把他们从硬件仓库(全局内存)可能把与这些数据相关的不同工作都执行了,避免发生“取来--存回--为了下一个工作再取”。

三、缓存一致性

       GPU与CPU在缓存上的一个重要差别就是“缓存一致性”问题。对于“缓存一致”的系统,一个内存的写操作需要通知所有核的各个级别的缓存。因此,无论何时,所有的处理器核看到的内存视图是完全一样的。随着处理器中核数量的增多,这个“通知”的开销迅速增大,使得“缓存一致性”成为限制一个处理器中核数量不能太多的一重要因素。“缓存一致”系统中最坏的情况是,一个内存操作会强迫每个核的缓存都进行更新,进而每个核都要对相邻的内存单元写操作。

      相比之下,非“缓存一致”系统不会自动地更新其他核的缓存。它需要由程序员写清楚每个处理器核输出的各自不同的目标区域。从程序的视角看,这支持一个核仅负责一个输出或者一个小的输出集。通常,CPU遵循“缓存一致性”原则,而GPU则不是。故GPU能够扩展到一个芯片内具有大数量的核心(流处理器簇)。

四、弗林分类法

      根据弗林分类法,计算机的结构类型有:

SIMD--单指令,多数据

MIMD--多指令,多数据

SISD--单指令,单数据

MISD--多指令,单数据

五、分条 / 分块

        CUDA提供的简单二维网格模型。对于很多问题,这样的模型就足够了。如果在一个块内,你的工作是线性分布的,那么你可以很好地将其他分解成CUDA块。由于在一个SM内,最多可以分配16个块,而在一个GPU内有16个(有些是32个)SM,所以问题分成256个甚至更多的块都可以。实际上,我们更倾向于把一个块内的元素总数限制为128、256、或者512,这样有助于在一个典型的数据集内划分出更多数量的块。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐