一、前言
本文将着重介绍GPGPU存储相关的架构。
二、存储系统概述
现代处置处罚器的存储系统大多接纳条理化的结构,本文将从 CPU 存储条理入手,通过对比介绍 GPGPU 存储条理的特点。
2.1 CPU 的条理化存储
在精简指令集计算机(Reduced Instruction Set Computer,RISC)中,运算器所需的操作数都需要从寄存器文件(Register File,RF)中获得。但寄存器的硬件开销很高,一个寄存器文件只能配备几十到数百个寄存器,所以运行时需要在寄存器文件和主存储器之间反复地举行操作数的加载(load)和存储(store)操作,包管运算所需要的操作数都能在寄存器中。但主存的访问速度很慢,会极大程度的影响处置处罚器性能。
为此,CPU 引入了高速缓存(cache)结构,将主存储器中常常被访问的数据保留在片上供快速访问。由于数据具有时间和空间局部性,把常用的数据公道地保留在高速缓存中,就可以进步数据访问的速度,并镌汰对主存储器访问的次数。由于高速缓存每每接纳读写速度更快的静态随机访问存储器(Static Random Access Memory,SRAM)来实现。然而,SRAM 集成密度低,其功耗较主存储器却大得多,使得高速缓存的容量仍远低于主存储器。依据高速缓存与运算器之间的距离,还可以将高速缓存细分为L1 Cache、L2 Cache 等。 一般而言,条理越低的缓存容量越大,但访问时间和性能代价也更高。
CPU存储系统中的条理化存储结构如下图所示:
该结构为典型的 “正三角” 金字塔、结构 。 不同存储介质有着不同的存储特性:顶部的存储介质离运算器近、速度快,但电路开销大,所以数目少,容量小;而底部的存储介质离运算器远,速度慢,但电路开销低,所以具有更大的容量。
现代 CPU 处置处罚器广泛将运算器、控制器、寄存器文件、缓存等部件集成封装在一块芯片内。其中寄存器和多级高速缓存构成了片上存储系统,而以 DRAM 为主要介质的主存储器放置在芯片外部,构成了外部存储系统。它们每每通过高速芯片组和总线与处置处罚器相连,与片上存储举行数据交互。
2.2 GPGPU 的存储条理
与 CPU 存储系统结构类似,GPGPU 的存储系统也接纳了条理化的结构设计,通过充分利用数据的局部性来低落片外存储器的访问开销。但为了满意 GPGPU 核心的 SIMT 大规模线程并行,GPGPU 遵照吞吐率优先的原则,因此其存储系统也与 CPU 有着显着区别。二者的差异主要表现在存储器容量、结构组成和访问管理上。
从上图(a)中可以看到,GPGPU 每个可编程多处置处罚器中寄存器文件的容量显著高于 L1 缓存和共享存储器,呈现出与 CPU 截然相反的“倒三角”结构。GPGPU 的寄存器文件接纳如此大容量的设计,主要是为了满意线程束的零开销切换。
GPGPU 的访存举动还表现出更为精细的片上存储管理特点。GPGPU 可以选择共享存储器、L1 数据缓存、纹理缓存、常量缓存等不同的存储空间来存储数据,还可以在包管总容量稳定的情况下机动地调节共享存储器和 L1 数据缓存的巨细。
三、寄存器文件
为了获取更高的寄存器存储密度,大容量的 GPGPU 寄存器文件多接纳 SRAM 实现。除了容量的需求,GPGPU 的寄存器文件还需要高并行度和高访问带宽以满意线程束对操作数并行访问的需求。 GPGPU 的寄存器文件接纳包含有多个板块(bank)的单端口 SRAM 来模拟多端口的访问。
3.1 并行多板块结构
下图展示了一个多板块组织的寄存器文件根本结构,其中数据存储部分由4个单端口的逻辑板块组成。由于寄存器操作数访问具有较高的随机性,这些逻辑板块接纳一个对等的交叉开关(crossbar)与 RR/EX(register read/execution)流水线寄存器相连,将读出的源操作数传递给 SIMT 执行单元。
执行单元的计算结果将被写回到其中的一个板块。 板块前端的访问仲裁器控制怎样对各个板块举行访问及交叉开关怎样将结果路由到合适的 RR/EX 流水线寄存器中。实际上,由于寄存器文件的总容量非常大,每个逻辑板块会被进一步拆分成更小的物理板块,以满意硬件电路对时序和功耗的约束。
在没有线程分支的情况下,寄存器文件将32个线程的标量寄存器打包成线程束寄存器(warped register)举行同一读取和写入,假设每个线程束最多配备8个线程束寄存器一种直接的分配方法就是将这8个寄存器依次分布到不同的逻辑板块中不同的线程束接纳雷同的方式分配各自的寄存器,如上图所示。
3.2 板块辩说和操作数网络器
但由于指令中寄存器的哀求每每呈现随机性,不均匀的哀求如果访问到同一板块,会导致单端口的逻辑板块发生板块辩说(bank conflict)。发生辩说的板块此时只能串行访问,依次读出所需要数据,导致板块利用率降落,低落寄存器访问的效率。以下是一个板块辩说示例:
假设有两条指令 i1 和 i2,其中指令 i1 是一条乘加指令,其源寄存器是 r5、r4 和 r6, 分别位于逻辑板块1、0和2(图中用“_ ”背面的数字表现)。指令 i2 是一条加法指令,其源寄存器均位于板块1的 r5 和 r1。右上表格展示了各线程束指令发射的顺序。源操作数不在同一板块的可以在一周期内拿到全部数。
3.2.1 操作数网络器
针对板块辩说导致的寄存器文件访问效率低落的问题,可以通过允许尽可能多的指令同时访问操作数,利用多板块的并行性进步来访问效率。这样即使板块辩说仍然存在,受益于寄存器访问的随机性,也可以重叠多条指令的访问时间,进步寄存器文件的吞吐量。
以下是一个包含操作数网络器的寄存器文件结构:
每条指令进入寄存器读取阶段后都会被分配一个操作数网络单元。 操作数网络器中包含多个网络单元,允许多条指令同时访问寄存器文件。
操作数网络器每每包含多个网络单元,以便进步寄存器并行访问的可能性。每个网络 单元包含一条线程束指令所需的所有源操作数的缓冲空间。因为每条指令至多可以包含3个源操作数寄存器,所以每个单元设置有3个条目,每个操作数条目又包含以下几个字段。
(1)1个有用位,表现指令中是否包含该操作数的哀求。
(2)1个寄存器 RID,代表该源操作数所在的寄存器编号。
(3)1个停当位,表明寄存器是否已经被读取,即后续操作数数据字段是否有用。
(4)操作数数据字段,每个操作数数据字段可以保存一个线程束所需的寄存器,即32比特× 32个线程=1024比特=128字节的数据。
(5)1个线程束 WID,用于指示该指令属于哪个线程束,与 RID 一起产生板块的访问地点。
当接收到一条解码指令并且有空闲的网络单元可用时,会将该网络单元分配给当前指令,并且设置好 WID、RID 和有用位。与此同时,源操作数寄存器读哀求在仲裁器中排队等待。仲裁器包含了每个板块的读哀求队列,队列中的哀求保留到访问数据返回为止。寄存器文件中有4个单端口逻辑板块,允许仲裁器同时将至多4个非辩说的访问发送到各个板块中。当寄存器文件完成对操作数的读取时,修改停当位为1。最后,当一个网络单元中所有的操作数都准备停当后,通知调度器将指令和数据发送给 SIMT 执行单元并释放其占用的网络器资源。
风险:操作数网络器目前只考虑了数据访问的并行性,虽然不同指令会按顺序进入操作数网络器,但对寄存器的访问和指令的执行没有任何顺序的约束,因此可能违背相关性导致流水线冒险。
针对操作数并行访问时产生的 WAR 冒险,可以要求每个线程束每次最多执行一条指令,只有在当前指令完成写回后才能发射下一条指令。或者让每个线程束每次仅允许一条指令在操作数网络器中网络数据。
寄存器的板块交错分布
将不同线程束同一编号的寄存器交错分布在各个板块中。如线程束 w0 的寄存器 r0 被分配在板块0中,而 w1 的寄存器 r0 分配在板块1中,这样如果 w0 和 w1 相继发射,它们仍然可以并行地从板块0和板块1中读取 各自的寄存器r0,消除了在访问雷同编号寄存器时存在的板块辩说问题。
3.3 寄存器文件的优化设计
增长前置寄存器文件缓存
有些数据的生命期很短且复用次数很低,将它们写入大容量的寄存器文件中再读取出来会浪费较高的能量。利用数据的局部性原理,通过增长一个小容量的寄存器文件缓存(Register File Cache,RFC)来捕获这些短生命周期的数据,从而过滤掉大部分对原有的主寄存器文件(Main Register File,MRF)的访问,进而低落功耗。
RFC的工作原理如下:待写回的目的寄存器起首会被写入 RFC 中,等待后续寄存器的读取操作。图像计算中,大部分目的寄存器会在较短的时间内仅有1次后续的读操作,因此可以通过 RFC 满意这部分读操作哀求。
给予嵌入式动态存储器的寄存器文件
传统的寄存器文件是基于 SRAM 设计的。在GPGPU 架构中,大容量的 SRAM 寄存器文件使得面积本钱和能耗成为瓶颈。嵌入式动态随机访问存储器(embedded-DRAM,eDRAM)提供了更高的存储密度和更低的静态功耗。
利用数据压缩的寄存器文件
(a)GPGPU 程序中许多局部变量都是通过线程 ID 天生的,而一个线程束中一连线程的线程 ID 仅相差1,因此用于存放数组访问地点的寄存器具有很强的值相似性。
(b)运行时输入数据的动态范围可能很小,会带来值相似性。
利用这样的相似性来对寄存器中存储的值举行压缩。
编译信息辅助的小型化寄存器文件
核心头脑是根据编译器天生的提示信息和分段算法,帮助硬件对寄存器完成实际的复用与管理。
四、SM 内的存储系统
4.1 数据通路概述
虽然GPGPU 的每个 SM 中都配备了大量寄存器文件,但其仍需要借助高速缓存来进一步低落访存延时,镌汰对外部存储器的访问次数。GPGPU 架构的特点使得高速缓存的设计不同于传统CPU。在 GPGPU 中 ,缓存根据其所处的条理分为 SM 内局部的数据缓存,如L1 数据缓存和可编程多处置处罚器外共享的数据缓存,如 L2 缓存。
L1数据缓存的一个显著特点是它可以与共享存储器(Shared memory)共享一块存储区域。
下图是NVIDIA GPGPU中 L1 数据缓存/共享存储器同一的结构和数据通路。其中⑤为二者共用的 SRAM 阵列,根据控制逻辑举行设置,可以实现一部分是数据缓存,另一部分是共享存储器的访问方式。
4.2 共享存储器访问
共享存储器中的数据是依次存储在各个 bank 中的,同一行内相邻 bank 间的地点是一连的,符合共享存储器的设计初衷。以"LDS Rdst,[addr]”指令为例,该指令中每个线程的[addr]都是独立计算的,那么32个线程在访问32个板块时就会产生32个地点,有以下两种可能:
(1)32个线程的地点可能分散在32个 bank 上,也可能指向同一个 bank 的雷同位置。
(2)32个线程的地点分别指向同一个 bank 的不同位置。
图(a)线程束中32线程依次访问32个不同的 bank;图(b)线程束中32个线程访问同一个 bank 的同一行;图(c)和(d)线程束中32个线程访问的目的地点中,有若干线程访问了雷同板块的不同行。(a)和(b)因为没有 bank 辩说,所以可以一次完成所有线程的访问。
无 bank 辩说时,共享存储器指令从 LSU(load/Store Unit)开始执行,根据指令类型识别出它是共享存储器的访问哀求后,LSU 会判断独立的线程地点之间是否会引起共享存储器的 Bank 辩说。如果不会引起板块辩说,那么仲裁器会担当并处置处罚这部分访存哀求,并控制地点交叉开关的打开与关闭。
这里关键要讲一下出现 Bank 辩说时的处置处罚方案:如果发生了 Bank 辩说,GPGPU 为此设计了 replay(重播)机制,针对一个 Warp 中访问同一个 Bank 的不同寄存器的线程来说,需要将各个线程“串行化”,通过对该条指令的反复 replay 来完成 Bank 辩说的线程对 Bank 的访问。不辩说的那些线程仍然可以一周期内访问 Shared memory 一次拿走数据。
4.3 L1 高速缓存
L1 数据缓存可以用来缓存全局存储器和局部存储器中可读可写的数据,但不同架构的写策略也有所不同。由于 GPGPU 中 L1 数据缓存一般不支持同等性,所以在写操作上会有一些特殊的设计。针对写掷中而言,根据被缓存数据属于哪个存储空间会接纳不同的写策略。例如,对于局部存储器的数据,可能是溢出的寄存器,也可能是线程的数组。由于都是线程私有的数据,写操作一般不会引起同等性问题,因此可以接纳写回(write back)策略,充分利用程序中的局部性镌汰对全局存储器的访问。对于全局存储器的数据, L1 数据缓存可以接纳写逐出(write evict)策略,将更新的数据写入共享 L2 缓存的同时将 L1 数据缓存中相应的缓存行置为无效(invalidation)。 由于许多 GPGPU 程序接纳了流处置处罚的方式来计算,全局存储器的数据可能本身也不具备良好的局部性可以利用,所以这种写逐出的策略包管了数据同等性,让更新的数据在全局存储空间可见。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |