3.3 三环近似

编程入门 行业动态 更新时间:2024-10-15 14:19:06

3.3 三环<a href=https://www.elefans.com/category/jswz/34/1765532.html style=近似"/>

3.3 三环近似

如前所述,为了隐藏长内存延迟,有必要支持每个内核的多个 warp 并支持 warp 之间的逐周期切换,有必要有一个大的寄存器文件,其中包含用于每个正在执行的 warp 的单独物理寄存器。 例如,此类寄存器在 NVIDIA 最近的 GPU 架构(例如 Kepler、Maxwell 和 Pascal 架构)上包含 256 KB。 现在,SRAM 存储器的面积与端口数成正比。 寄存器文件的简单实现要求每个操作数每个周期发出的每个指令一个端口。 减少寄存器文件面积的一种方法是使用多组单端口存储器来模拟大量端口。 虽然可以通过将这些库暴露于指令集架构来实现此类效果,但在某些 GPU 设计中,它出现了一种称为操作数收集器的结构 [Coon et al., 2009, Lindholm et al., 2008b, Lui et al. , 2008] 用于以更透明的方式实现这一目标。 操作数收集器有效地形成第三个调度循环,如下所述。

为了更好地理解操作数收集器解决的问题,首先考虑图 3.12,它显示了用于提供增加的寄存器文件带宽的朴素微体系结构。 此图显示了 GPU 指令流水线的寄存器读取阶段,其中寄存器文件由四个单端口逻辑寄存器组组成。 实际上,由于寄存器文件非常大,每个逻辑bank可以进一步分解成更多的物理bank(未示出)。 逻辑bank通过交叉开关连接到分级寄存器(标记为“流水线寄存器”),在将源操作数传递给 SIMD 执行单元之前缓冲源操作数。 仲裁器控制对各个bank的访问,并通过交叉开关将结果路由到适当的流水线寄存器。

图 3.13 显示了每个 warp 的寄存器到逻辑bank的简单布局。 在此图中,来自 warp 0 (w0) 的寄存器 r0 存储在 Bank 0 的第一个位置,来自 warp 0 的寄存器 r1 存储在 Bank 1 的第一个位置,依此类推。 如果计算所需的寄存器数量大于逻辑bank的数量,则分配回绕。 例如,warp 0 的寄存器 r4 存储在 Bank 0.7 的第二个位置.

 

 图 3.14 说明了一个时序示例,突出显示了这种微体系结构如何导致性能下降。 该示例涉及顶部显示的两条指令。 第一条指令 i1 是一个乘加操作,它从分配在 bank 1、0 和 2 中的寄存器 r5、r4 和 r6 中读取(图中用下标表示)。 第二条指令 i2 是一条加法指令,它从分配在bank 1 中的寄存器 r5 和 r1 读取。图的中间部分显示了指令发出的顺序。 在周期 0 上,warp 3 发出指令 i1,在周期 1 上,warp 0 发出指令 i2,在周期 4 上,warp 1 在由于存储体冲突而延迟后发出指令 i2,如下所述。 该图的底部说明了不同指令访问不同bank的时序。 在第 1 周期,来自 warp 3 的指令 i1 能够在第 1 周期读取其所有三个源寄存器,因为它们映射到不同的bank。 然而,在第 2 个周期,来自 warp 0 的指令 i2 只能读取它的两个源寄存器之一,因为它们都映射到 bank 1。在第 3 个周期,该指令的第二个源寄存器读取与warp 3的指令 i1 的写回并行发生。在第 4 周期,来自 warp 1 的指令 i2 能够读取其第一个源操作数,但不能读取第二个源操作数,因为两者都映射到 bank 1。在第 5 个周期,来自 warp 1 的指令 i2 的第二个源操作数 1 被阻止从寄存器文件中读取,因为 bank 1已经被 warp 0 之前发出的指令 i2 的更高优先级的写回访问。最后,在周期 6,来自 warp 1 的 i2 的第二个源操作数从寄存器文件中读取。 总之,三个指令需要六个周期才能完成读取它们源寄存器,并且在此期间许多bank未被访问。

3.3.1 操作数收集器

 操作数收集器微架构 [Lindholm et al., 2008b] 如图 3.15 所示。 关键变化是暂存寄存器已被收集器单元取代。 每条指令在进入寄存器读阶段时都会分配一个收集器单元。 有多个收集器单元,因此多个指令可以重叠读取源操作数,这有助于在单个指令的源操作数之间存在bank冲突时提高吞吐量。 每个收集器单元都包含用于执行指令所需的所有源操作数的缓冲空间。 鉴于多条指令的源操作数数量较多,仲裁器更有可能实现更高的bank级并行性,以允许并行访问多个寄存器文件bank。

操作数收集器使用调度来容忍bank冲突。 这留下了如何减少bank冲突数量的问题。 图 3.16 说明了修改后的寄存器布局。 Coon 等人认为这有助于减少bank冲突。 这个想法是在不同的bank中分配来自不同 warp 的等效寄存器。 例如,在图 3.16 中,warp 0 的寄存器 r0 分配给 bank 0,而 warp 1 的寄存器 r0 分配给 bank 1。这不会解决单个指令的寄存器操作数之间的 bank 冲突。 然而,它确实有助于减少来自不同 warp 的指令之间的 bank 冲突。 特别是,每当 warps 取得相对均匀的进展时(例如,由于循环调度或两级调度 [Narasiman et al., 2011],其中获取组中的各个 warps 按循环顺序调度)。

 图 3.17 显示了一个时序示例,顶部显示了一系列加法和乘加指令。 中间显示了发射顺序。 来自 warp 1 到 3 的 i1 的三个实例在周期 0 到 2 上发出。来自 warp 0 的指令 i2 的实例在周期 3 上发出。请注意,对于任何给定的 warp,add 指令写入的寄存器 r1都和作为源寄存器 r5分配在同一个 bank 。 然而,与图 3.13 中使用寄存器布局的情况不同,这里不同的 warp 访问不同的 bank,这有助于减少一个 warp 的写回和读取其他 warp 中的源操作数之间的冲突。 底部显示了由于操作数收集器而导致的bank级访问时序。 在周期 1 中,warp 1 中的寄存器 r2 读取 Bank 3。在周期 4 中,注意 warp 1 中的寄存器 r1 的写回与从 warp 3 中读取寄存器 r5 和从 warp 0 中读取寄存器 r3 并行进行。

到目前为止所描述的,操作数收集器存在一个微妙问题 ,因为它不会在不同指令准备好发出之间强加任何顺序,所以它可能会导致读后写 (WAR) 危害 [Mishkin et al., 2016]。 如果来自同一 warp 的两条指令出现在操作数收集器中,并且第一条指令读取第二条指令将写入的寄存器,则会发生这种情况。 如果第一条指令的源操作数访问遇到重复bank冲突,那么可以想象第二条指令可以在第一条寄存器读取(正确的)旧值之前将新值写入寄存器。 防止这种 WAR 危险的一种方法是简单地要求来自同一 warp 的指令按程序顺序执行。 米什金等。 [2016] 探索三种具有低硬件复杂性的潜在解决方案并评估它们的性能影响。 第一个是提交时发布的 warpboard(release-on-commit warpboard),它允许每个 warp 最多执行一条指令。 不出所料,他们发现这会对性能产生负面影响,在某些情况下性能几乎降低两倍。 他们的第二个提议是一个读取时释放的 warpboard(release-on-read warpboard),它允许每个 warp 一次只允许一条指令在操作数收集器中收集操作数。 该方案导致他们研究的工作负载最多减慢 10%。 最后,为了在操作数收集器中实现指令级并行性,他们提出了一种布隆板机制(bloomboard),该机制使用小型布隆过滤器来跟踪未完成的寄存器读取。 这导致影响小于百分之几与(错误地)允许 WAR 危险。 另外,Gray 进行的一项分析表明 NVIDIA 的 Maxwell GPU 引入了一个“读取依赖屏障”,它由特殊的“控制指令”管理,可用于避免某些指令的 WAR 危险(参见第 2.2.1 节)。

3.3.2 指令重放:处理结构性冲突

GPU 流水线中存在结构性危险的许多潜在原因。 例如,寄存器读取阶段可能用完操作数收集器单元。 许多结构性风险的来源都与存储系统有关,我们将在下一章更详细地讨论。 通常,由 warp 执行的单个内存指令可能需要分解为多个单独的操作。 这些单独的操作中的每一个都可以在给定周期内充分利用管道的一部分。

当指令在 GPU 流水线中遇到结构性冲突时会发生什么? 在单线程有序 CPU 流水线中,标准解决方案是停止较新的指令,直到遇到停止条件的指令可以继续执行。 由于至少两个原因,这种方法在高度多线程吞吐量体系结构中不太受欢迎。 首先,鉴于寄存器文件的大小以及支持完整图形流水线所需的许多流水线阶段,分配停顿信号可能会影响关键路径。 流水线停顿周期分配导致需要引入额外的缓冲增加区域。 其次,拖延来自一个 warp 的指令可能会导致来自其他 warp 的指令在它后面拖延。 如果这些指令不需要导致停顿的指令所需的资源,吞吐量可能会受到影响。

为了避免这些问题,GPU 实施了一种指令重放形式。 在一些 CPU 设计中有指令重放,在这些设计中,当根据具有可变延迟的较早指令推测性地调度相关指令时,指令重放被用作恢复机制。 例如,LOAD指令在一级缓存中可能命中或未命中,但高频运行的 CPU 设计可能会在四个时钟周期内流水线式访问一级缓存。 一些 CPU 在load之后推测性地唤醒指令来提高单线程性能。 相比之下,GPU 避免推测,因为它往往会浪费能量并降低吞吐量。 相反,在 GPU 中使用指令重放来避免阻塞流水线,避免电路区域开销和/或因停滞导致的时序开销。

为了实现指令重放,GPU 可以将指令保存在指令缓冲区中,直到知道它们已经完成或指令的所有单独部分都已执行 [Lindholm et al., 2015]

更多推荐

3.3 三环近似

本文发布于:2024-03-10 17:17:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1728564.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:近似   三环

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!