7.5 私有内存
私有内存指的是各工作项内自己所使用的变量,也包括内核参数。原则上,私有数据通常放置到寄存器上,不过寄存器的资源并不是那么多,当使用的私有内存过多时,一部分数据将会放置到全局内存中。私有内存的分配会影响内核所使用到的寄存器数量。与局部内存一样,指定的架构中所分配的寄存器数量是固定的。而且,不同架构之间的性能差异也很大。
x86类型的CPU所具有的寄存器数量相当少。不过,因为其缓存较大,一些需要将寄存器上的数据放置到栈上的操作,以及将数据返回寄存器的操作,都会在缓存和寄存器之间交换数据,所以这些操作几乎没有什么延迟。使用寄存器时,需要把使用频率较高的数据放在寄存器上,这样这些变量从作用域中的出入将会变的十分高效。
GPU上就不能这样奢侈的使用缓存。有些设备没有读写缓存,有些有缓存的设备上,缓存也十分有限,因此在寄存器也很有限的情况下,工作项所需要的数据很快会填满缓存,这样将会导致有些数据在再需要的时候,在缓存上未命中。设备上的DRAM被填满时,该设备的性能会急剧恶化。开发应用时,需要尽量避免这种情况的发生。
如果寄存器够用,寄存器对于GPU上大量的激活线程时,其功能与局部数据共享(LDS, local data share)的方式很相似(将在第8章进行详细描述)。ADM Radeon HD R9 290X架构中,每个计算单元具有256KB寄存器内存。其有4块(SIMD)寄存器块,每个寄存器块具有256个寄存器,每个寄存器的每个通道能够处理4字节64位宽向量。如果每个工作项使用100个寄存器,那么对于SIMD来说,只能发送出有2波数据,几乎没有什么指令延迟隐藏。而当每个工作项使用49个寄存器时,那么就可以发出5波数据,这样就能很好的隐藏指令延迟。
虽然,数据转移在寄存器中处理起来更加高效,不过这样会消耗掉计算核中的一些线程束,无法进行延迟隐藏,并且这样会导致更多缓存数据交换操作,从而浪费更多GPU计算周期。