● 欲求不满的寄存器
寄存器同显存和cache一样,都是发源于CPU的重要缓冲组成部分。长期以来,寄存器都伴随在运算单元旁边,以最及时的延迟和最大的带宽为运算单元提供着指令寄存空间(IR)、程序计数缓冲(PC)以及累加器(ACC)等多方面的服务。
常规6bit指令寄存器结构
寄存器可以为运算器提供最快速的临近临时存储,让它们释放结果、挂起数据或者弯成回溯之类的事情。几乎每一个运算单元的每一次动作到有寄存器参与的身影。由于通常拥有最高的运行速度以及0t的延迟,GPU常用的32bit寄存器相当耗费晶体管资源,这让它们的身价更加倍增。由于无法随心所欲的配置大量寄存器,每一个运算单元能够分配到的寄存器资源都非常的少。以G80为例,每个SM包含8个SP单元,而寄存器总量仅为32K,每个ALU仅能分到4K 32bit寄存器资源。而R600极其系列衍生构架则更是少到了平均3.3K/ALU的水平,直到Cayman构架才补足到了4K。
NVIDIA GPU的寄存器资源自G80以来一直相对充足
对于ALU来说,条件允许的前提下对寄存器的需求近乎是无限的,这种需索无度与寄存器相对稀少的现实总量形成了鲜明的对比。我们在GPU大百科番外篇对NV3X构架的分析中可以看出,寄存器无节制溢出的后果是可怕的,因此程序员们除了小心谨慎的处理自己手头的程序需求,尽量让ALU在现有资源总量允许的前提下对寄存器进行使用之外,就只有祈祷硬件准备了充分的寄存器溢出缓冲以备不时之需了。
cache是很好的寄存器缓冲溢出,虽然它的速度和延迟相对于寄存器来说差了不少,但依旧可以在编程环境处理得当的前提下发挥很好的延迟掩盖作用。而unified cache在GPU中出现之前,GPU中大大小小的各种“cache”并不能通用,因此也就不能随心所欲的发挥应有的作用了。cache之外,接下来可供选择的途径就只剩显存一途了,显存的空间对于ALU来说虽然可以大到近乎无限,但显存的低带宽和高延迟让其在相当长的一段时间内都不具备参与核心缓冲的能力。最早使用显存来充当寄存器溢出缓冲的NV30带来了几乎是灾难性的表现,直到与MC配合之后带宽突破100G甚至接近200G的GDDR5出现之后,显存才具备了充当寄存器溢出缓冲的条件。而此时Fermi中unified cache的引入,也适时的将寄存器和显存这对速度差异仍旧巨大的缓冲连接在了一起。
Fermi的cache体系已经彻底将寄存器和显存联系在了一起
同GPU的很多单元一样,存储体系终于也在各自为战甚至陷入混沌相当长一段时间之后,再度呈现了统一的趋势。