- 第五章 流控制 flow control
第五章 流控制 flow control
流量控制(flow control)控制网络缓冲区和链路的分配。它确定缓冲区和链路何时分配给消息、分配的粒度以及如何在使用网络的许多消息之间共享这些资源。良好的流控制协议不会在资源分配中施加高开销,从而降低低负载下消息所经历的延迟,并通过实现跨消息的缓冲区和链接的有效共享来提高网络吞吐量。在确定数据包访问缓冲区(或完全跳过缓冲区访问)和在链路中传输的频率时,流量控制有助于确定网络能量和功耗。流量控制协议的实现复杂性包括路由器微体系结构的复杂性以及在路由器之间传递资源信息所需的布线开销。
5.1 消息、数据包、flit和phit
当消息注入网络时,它首先被分段为数据包,然后将消息数据包分成固定长度的 flits(流量控制单元 flow control unit 的缩写,为流控制中最小粒度数据单元)。例如在多核芯片中,从共享者发送到请求者的 128 字节缓存行将作为消息注入网络。如果最大数据包大小大于 128 字节,则整个消息将被编码为单个数据包。
该数据包将由包含目标地址的头flit(head flit)、包含数据主体的体flit(body flit),以及指示数据包结束的尾flit(tail flit)组成。
flit可以进一步分解为phit(phit 是physical transfer unit的缩写,其为物理传输最小粒度数据单元)。这是物理单位,phits 对应于物理通道宽度。消息到数据包和数据包到 flits 的细分如图 5.1a 所示;图b所示,如果 flit 大小为 128 位即16字节,则一个64字节大小的高速缓存行数据包需要5个flit组成;图c中,一个缓存一致性命令数据包只有一个单独的flit。
序列号Seq#用于将输入的响应和未决请求相匹配,或确保数据包的通信顺序及检测丢失的数据包。
此外,flit中还包含一部分控制信息,如数据流类型和虚拟通道编号。如果 flit 大小为 128 位,则 128 字节数据包将由 8 个 flit 组成:1 个头、6 个主体和 1 个尾部,忽略对目的地进行编码所需的额外位以及流量控制协议所需的其他信息。简而言之,消息是网络之上通信的逻辑单元,而数据包是对网络有意义的物理单元。数据包包含目的地信息,而flit可能不包含目的地信息,因此数据包的所有flit必须采用相同的路由。
由于片上布线资源丰富,片上网络中的通道往往更宽,因此消息很可能由单个数据包组成。在片外网络中,通道宽度受到引脚带宽的限制;这种限制导致 flits 被分解为更小的块,称为 phits。迄今为止,在片上网络中,flit 由单个 phit 组成,并且由于片上通道较宽,是消息的最小细分。此外,如图 5.1 所示,许多消息实际上是单片数据包。例如,一致性命令只需要携带命令和可以容纳在16字节宽的片中的存储器地址。流量控制技术按资源分配发生的粒度进行分类。
5.2 基于消息的流控制 Message-based flow control
电路交换是一种在消息级别(最粗粒度)运行的技术。电路交换跨多跳将资源(链路)预先分配给整个消息。
探测消息(probe)被发送到网络中,并保留将整个消息(或多个消息)从源传输到目的地所需的链路。一旦探测器到达目的地(已成功分配必要的链路),目的地就会将确认消息发送回源。当源收到确认消息时,它会释放该消息,然后该消息可以在网络中快速传播。一旦消息完成其遍历,资源就会被释放。
建立路径阶段之后,就可以避免因需要获取资源而增加的每跳的延迟。对于足够大的消息,电路交换路由的整体传输延迟很低,因为建立预留资源的延迟(源-目标的节点对建立消息和确认消息的传输延迟)占比很小。除了可能的延迟优势之外,电路交换也是无缓冲的。由于链路是预先保留的,因此每一跳不需要缓冲区来保存等待分配的数据包,从而节省了电力。
虽然其可以减少延迟,但电路交换会遇到带宽利用率低的问题。因为资源已经预留给指定的节点对,其他的节点对需要使用资源的时候就要被阻塞,降低了带宽的利用率。图5.2 显示了电路交换流量控制示例,计算核心0到8的数据传输过程。
假设图5.2采用X-Y维序路由。首先建立flits穿越指定路径预留从核心0到核心8的传输电路。时刻4建立flit到达了目的节点,并开始向计算核心0发送确认flit。在时刻5核心2想发起到核心8的另外一个消息传输,但是已经分配给计算核心0,因此请求被阻塞。在时刻9核心0受到确认flit并开始传输数据。一旦完成数据传输,核心0就会发送tail flit来释放预留资源。
存在大量的链路带宽浪费。在建立时间期间以及当链路已被保留但没有需要传输的数据时,这些链路处于空闲状态但不可用于其他消息(浪费的链路带宽以灰色阴影显示)。 Core 2 在等待大部分闲置资源时也会遭受严重的延迟。
5.3 基于数据包的流控制
电路交换为消息分配资源,并跨多个网络跃点进行分配。该方案存在一些效率低下的问题;接下来,我们看看为数据包分配资源的方案。基于数据包的流量控制技术首先将消息分解为数据包,然后将这些数据包交织在链路上,从而提高链路利用率。与电路交换不同,其余技术将需要每个节点缓冲来存储传输中的数据包。
5.3.1 存储转发流控制 STORE AND FORWARD
使用基于数据包的技术,消息被分解为多个数据包,每个数据包由网络独立处理。在存储转发流控制中,每个节点都会等待,直到接收到整个数据包,然后再将数据包的任何部分转发到下一个节点。因此,每一跳都会产生较长的延迟,这使得它们不适合通常对延迟至关重要的片上网络。
此外,存储和转发流量控制要求每个路由器有足够的缓冲来缓冲整个数据包。这些高缓冲要求降低了存储和转发交换对片上网络的适应性。在图 5.3 中,我们描述了使用存储转发交换从 Core 0 传输到 Core 8 的数据包。一旦尾部流片在每个节点被缓冲,头部就可以分配下一个链路并前往下一个路由器。在每一跳中head flit需要等待body flit和tail flit 都到达后才会向后发送,因此会带来串行化延迟。对于 5-flit 数据包,每跳传输数据包的延迟为 5 个周期。
5.3.2 虚拟直通流控制 VIRTUAL CUT-THROUGH
虚拟直通 为了减少数据包在每一跳的延迟,虚拟直通流量控制允许在当前路由器接收到整个数据包之前将数据包传输到下一个节点。因此,通过存储和转发流量控制,数据包所经历的延迟大大减少,如图 5.4a 所示。在图5.3中,传输整个数据包需要25个周期;通过虚拟直通,该延迟可减少至 9 个周期。
然而,带宽和存储仍然以数据包大小的单位进行分配。仅当下一个下游路由器有足够的存储空间来容纳整个数据包时,数据包才会继续前进。当数据包大小较大(例如 64 或 128 字节高速缓存行)时,面积和功率限制有限的片上网络可能很难容纳支持虚拟直通所需的大型缓冲区。
在图 5.4b 中,即使节点 5 具有可用于 5 个 flits 中的 2 个的缓冲区,整个数据包在从节点 2 传输到节点 5 时也会发生延迟,因为无法容纳一个数据包5个flits的大小。在所有 5 个 flit 缓冲区都可用之前,任何 flit 都无法继续。
总结:
存储转发和虚拟直通流控制都是基于数据包粒度去分配缓冲区和链路的。具体来说就是下游节点需要有一个数据包大小的空闲缓冲区才能继续发送,另外传输过程中链路保留,其他数据包不能使用。唯一的区别就在于虚拟直通允许数据包未完全到达之前进行传输。
5.4 基于flit的流控制
为了减少基于数据包的技术的缓冲要求,存在基于flit的流控制机制。低缓冲要求有助于路由器满足芯片上的狭小面积或功率限制。
WORMHOLE(虫洞流控制)与虚拟直通流量控制一样,虫洞流量控制传输 flits,允许 flits 在当前位置接收到整个数据包之前移动到下一个路由器。对于虫洞流量控制,只要有足够的缓冲,该 flit 就可以离开当前节点。然而,与存储转发和虚拟直通流量控制不同,虫洞流量控制将存储和带宽分配给flit而不是整个数据包。这允许在每个路由器中使用相对较小的 flit 缓冲区,即使对于较大的数据包也是如此。
需要注意的是,虽然虫洞流控制可以有效利用缓冲区,但是其无法有效利用链路带宽。尽管它以 flit 大小的单位分配存储和带宽,但是路由器中的链路在整个数据包的传输期间将被占用。这导致当数据包阻塞时,该数据包占用的所有物理链路仍然无法继续传输,即都处于闲置状态。由于虫洞流控制以flit粒度分配缓冲区,因此由多个flit组成的数据包可能跨越多个路由器,这将导致许多空闲的物理链路。由于在被阻止数据包后面排队的其他数据包无法使用空闲的物理链路,因此吞吐量会受到影响。
在图 5.5 的示例中,每个路由器有 2 个 flit 缓冲区。当头部 flit 经历从 1 到 2 的争用(假设缓冲区已满)时,剩余的两个主体和尾部 flit 会在核心 0 处停滞,因为核心 1 处没有可用的缓冲区空间,直到头部移动到核心 2。然而,通道仍然由即使数据包处于空闲状态(如灰色所示)。
虫洞流量控制通过在下游缓冲区可用时允许 flit 立即离开路由器来减少数据包延迟(在没有争用的情况下,延迟与虚拟直通相同)。此外,与基于数据包的技术相比,虫洞流量控制可以使用更少的缓冲区来实现。由于片上网络的面积和功率限制,虫洞流量控制是迄今为止采用的主要技术。
5.5 虚拟通道流控制
虚拟通道被解释为互连网络的“瑞士军刀”。它们最初被提出作为避免死锁的解决方案,但也被应用于减轻流控制中的队头阻塞(head-of-line blocking),从而提高吞吐量。队头阻塞发生在所有上述流量控制技术中,其中每个输入都有一个队列,当队列头部的数据包被阻塞时,即使有可用资源用于停顿的数据包,它也会阻止排在其后面的后续数据包。
本质上,虚拟通道(Virtual Channel, VC)基本上是路由器中的一个单独的队列;多个 VC 虚拟通道时分复用共享两个路由器之间的物理线路(物理链路)。通过赋予每个输入端口多个单独的队列,可以减少队头阻塞。虚拟通道以时钟周期为控制粒度,仲裁物理链路带宽的分配。当持有虚拟通道的数据包被阻塞时,其他数据包仍然可以通过其他虚拟通道穿越物理链路。因此,VC 提高了物理链路的利用率并扩展了整体网络吞吐量。
从技术上讲,VC 可以应用于所有上述流量控制技术,以减轻队头阻塞,尽管 Dally 首先通过虫洞流量控制提出了它们。例如,电路交换可以应用在虚拟通道上,而不是物理通道上,因此消息中保留了一系列的VC而不是物理链路,这些VC逐周期时分复用到物理链路上,也称为虚拟电路交换。存储转发流量控制也可以与 VC 一起使用,具有多个数据包缓冲队列,每个 VC 一个,VC 在链路上逐个数据包复用。使用 VC 的虚拟直通流量控制的工作原理类似,只是 VC 在链路上逐个复用。然而,由于片上网络设计绝大多数采用虫洞流控制,因为其面积小、功耗小,并在需要时使用虚拟通道来扩展带宽,因此在本书的其余部分中,当我们提到虚拟通道流控制时,我们假设它应用于虫洞,以 flits 的粒度管理和复用缓冲区和链路。
图 5.6 描述了说明虚拟通道流量控制操作的示例。数据包 A 初始占用 VC 0,目的地为节点 4,数据包 B 初始占用 VC 1,目的地为节点 2。在时间 0,数据包 A 和数据包 B 都有flit 在节点 0 的西输入虚拟通道中等待,并希望在东向输出物理通道上出站。假设数据包 A 的头部 flit 被分配给路由器 1 西侧输入的虚拟通道 0,并赢得交换机分配,数据包 A 的头flit在时间 1 传输到路由器 1。
在时刻2,数据包B在开关分配中获得批准,从而传输到路由器1中。同时路由器4两个输入端口虚拟通道都被占用,因此数据包A的头flit没有分配到虚拟通道,从而无法前往下一跳。
在时刻3,数据包A的第一个body flit继承了虚拟通道前往路由器1,同时数据包B的head flit被分配到下游节点路由器2的VC0并继续前进。
在时刻4,数据包B继承了虚拟通道,赢得开关分配后前往路由器1。
…
在时刻7,B的除尾flit所有flit都已到达目的地,而数据包A头flit仍被阻塞,只有路由器4有空闲的虚拟通道后才能传输。
通过使用单个虚拟通道的虫洞流量控制,数据包 B 将在路由器 1 处被阻塞在数据包 A 之后,并且无法继续到达路由器 2,尽管有可用的缓冲区、链路和交换机来执行此操作。尽管数据包 A 被阻塞,虚拟通道仍允许数据包 B 继续前往其目的地。通过虚拟通道流量控制,不同数据包的 flits 可以在同一物理通道上交错,如时间 0 和 2 之间的示例所示。虚拟通道也广泛用于打破网络内的死锁,以及处理系统级或协议级死锁。
flow control techniques | Links | Buffers | Comments |
---|---|---|---|
Circuit-Switching | Messages | N/A (buffer-less) | Requires setup and acknowledgment |
Store and Forward | Packet | Packet | Head flit must wait for entire packet before proceeding on next link |
Virtual Cut Trough | Packet | Packet | Head can begin next link traversal before tail arrives at current node |
Wormhole | Packet | Flit | Head of line blocking reduces efficiency of link bandwidth |
Virtual Channel | Flit | Flit | Can interleave flits of different packets on links |
5.6 无死锁流控制
可以通过使用确保不会发生循环的约束路由算法(参见第 4 章)或通过使用允许使用任何路由算法的无死锁流控制来保持死锁自由。
5.6.1 日期变更线Dateline 和 VC 分区
图 5.7 说明了当路由协议允许循环时,如何使用两个虚拟通道来打破网络中的循环死锁。这里,由于每个VC与单独的缓冲队列相关联,并且每个VC逐周期时间复用到物理链路上,所以保持VC意味着保持其关联的缓冲队列而不是锁定物理链路。通过给虚拟通道制定优先级,强制规定较低优先级的虚拟通道无法请求和获得更高优先级的虚拟通道的传输权限,可以确保在资源的依赖关系中不会出现循环。在图 5.7 中,所有消息都通过 VC 0 发送,直到跨越日期变更线。跨越日期变更线后,消息将被分配给 VC 1,并且在其网络遍历的剩余时间内的任何时候都不能分配给 VC 0 ,这确保了通道依赖图(CDG)是非循环的。
时间线是避免死锁的一种技术,位于拓扑某个维度的连路上,是人为设定的一个虚拟位置。每个维度上都会预设一个时间线。当flit穿过时间线,则flit会从当前vc通道转向另一个虚拟通道来防止死锁。
同样的想法适用于各种不经意/自适应路由算法,这些算法允许所有转弯,因此很容易出现死锁。在 X-Y 和 Y-X 路由之间随机选择的路由算法可以通过强制所有 X-Y 数据包使用 VC 0 以及所有 Y-X 数据包使用 VC 1 来实现无死锁。类似地,希望允许所有轮次实现路径分集的路由算法可以是通过在 VC 0 中实现某个转向模型并在 VC 1 中实现另一个转向模型,并且不允许一个 VC 中的数据包在整个遍历过程中跳转到另一个 VC,从而实现无死锁。
在系统级别,可以将可能相互阻塞的消息分配给映射到网络内不同虚拟通道的不同消息类别,例如一致性协议的请求和确认消息。这些设计通过将所有可用的 VC 划分为多个类并在这些类中强制执行上述排序规则来扩展到多个 VC。在每个类别中,flit 可以获得任何 VC。
5.6.2 ESCAPE VCS 逃逸通道
在 VC 之间强制排序以防止死锁的好处。然而,对 VC 强制执行命令会降低其利用率,从而在 VC 数量较少时影响网络吞吐量。
Duato提出 Escape VC 来解决这个问题。 Duato 证明了非循环 CDG 的要求是无死锁路由算法的充分条件,但不是必需的;即使CDG是循环的,只要CDG存在非循环子部分,就可以用来摆脱循环依赖性。 CDG 的这个非循环连接的子部分定义了逃逸虚拟通道。
因此,逃逸VC不是在所有VC之间强制执行固定顺序/优先级,只要存在一个无死锁的逃逸VC,所有其他VC就可以使用完全自适应路由而没有路由限制。该逃逸 VC 通常通过使用其中的无死锁路由功能来实现无死锁。例如,如果将 VC 0 指定为逃逸通道,则 VC 0 上的所有流量必须使用维度排序路由进行路由,而所有其他 VC 可以使用任意路由功能进行路由。简而言之,只要对 VC 的访问得到公平仲裁,数据包总有机会到达逃逸 VC,从而避免死锁。逃逸 VC 有助于提高 VC 的利用率,或者通过较少数量的VC通道去实现更高的吞吐量,从而使路由器更精简。
在图 5.8a 中说明了单个虚拟通道的无限制路由如何导致死锁。每个数据包都试图获取资源以进行顺时针转动。图 5.8b 使用两个虚拟通道。VC1作为逃生虚拟通道。例如,数据包 A 可以被分配虚拟通道 1(因此维度顺序路由到其目的地),所有数据包都可以转发。数据包 A 的 flits 最终将从路由器 1 处的 VC 0 排出,从而允许将数据包 B 分配到路由器 1 处的任一虚拟通道。一旦数据包 B 的 flits 耗尽,数据包 D 可以传输到路由器0的任意VC通道。对于数据包 C 的 flits 也是如此。
5.6.3 BUBBLE FLOW CONTROL 气泡流量控制
避免死锁而不需要多个 VC 类的另一种想法是确保缓冲区之间永远不会在运行时创建封闭的循环依赖关系。由于每个维度都存在环形网络,k 元、n 元立方体容易出现死锁。即使使用 DOR 等无死锁路由,该环形网络也会固有地产生循环依赖性。气泡流控制与虚拟直通结合使用,以在 k 元、n 元网络中提供无死锁。即在特定维度内传输的数据包仍采用虚拟直通流量控制正常处理。需要有数据包注入网络或更改维度的基于气泡流控制进行处理。
要求当环中存在两个数据包大小的缓冲区空间数据包才能被注入,这样可以保证环中仍然有一个空的数据包缓冲区,这一空缓冲区(称为“气泡”,bubble)可确保环中至少有一个数据包能够向前推进,从而防止死锁。图 5.9 显示了一个示例,其中 R1 有两个空气泡,这将允许注入数据包 P1。其余路由器只有一个空闲气泡,分别阻止数据包 P0 和 P2 的注入。该规则同样适用于更改维度传输的数据包,把它们看作新注入的数据包处理。
由于搜索环中所有缓冲区的复杂性不具有可行性,气泡流控制要求本地队列中有两个空数据包缓冲区才能注入数据包,这提高了最小缓冲区尺寸的要求,且不利于片上网络的小面积小功率的需要。已经有一些工作研究如何将气泡流应用于虫洞流控制技术以降低缓冲区要求,更好地兼容片上网络。
5.7 缓冲区反压 buffer backpressure
由于大多数片上网络设计不能容忍数据包丢失,因此必须有缓冲区反压机制来阻止 flits。当下一跳没有可用的缓冲区来容纳 Flit 时,不得传输它们。buffer backpressure的单位粒度取决于具体的流控协议。存储转发和虚拟直通流量控制技术以数据包为单位管理缓冲区,而虫洞和虚拟通道流量控制以flit为单位管理缓冲区。电路交换是一种无缓冲流量控制技术,不需要缓冲反压机制。两种常用的缓冲区反压机制是基于credit的缓冲区反压机制和基于开启/关闭信号的缓冲区反压机制。
5.7.1 credit-based 基于credit的缓冲区反压机制
credit计数器记录了下一跳路由器空闲缓冲区的个数。每个节点空出缓冲区时(当flit/数据包离开路由器时)向前一跳发送credit。前一跳路由器接受credit后递增credit计数。当一个flit离开当前路由器时,当前路由器会减少相应下游缓冲区的credit计数。
credit计数器记录的是下一跳路由器缓冲区空闲空间还能存储多少个flit。当前路由器可以根据credit计数决定继续或暂停传输数据包。若当前credit减为零则表示下一跳没有空闲缓冲区,需停止传输。一旦下一跳路由器发送出一个flit,被占据的缓冲区就会释放一个单位,因此下一跳路由器会向当前路由器发送信号使credit计数加1。一般每个端口的每个VC通道都会由上游路由器维护单独的一个CR。
5.7.2 on/off 基于开启/关闭信号的缓冲区反压机制
开启关闭信号指的是相邻路由器之间的一个信号。当下一跳路由器空闲缓冲区的数量缓冲区数量达到关闭阈值时,该信号就会被关闭(off-signal)以阻止当前路由器继续发送flit。关闭阈值的设定必须确保正在传输的flit在抵达时都有相应的缓冲区。在关闭信号传输过程中,必须为离开当前路由器的flit提供缓冲区。一旦下一跳路由器空闲缓冲区数量超过开启阈值,开启信号(on-signal)以使当前路由器恢复flit传输。开启阈值时,在开启信号发送时下游路由器缓冲区不应为空,而是需要有可容纳flit的缓冲区以覆盖信号传输的延迟,提高带宽利用率。
5.8 流控制协议的实现
流量控制协议的实现复杂性本质上涉及整个路由器微体系结构的复杂性以及路由器之间传递资源信息所带来的布线开销。在这里,我们重点关注后者,因为第 6 章详细阐述了路由器微体系结构和相关的实现问题。当选择特定的缓冲区反压机制时,我们需要考虑其缓冲区周转时间方面的性能,以及反向信号线数量方面的开销。
5.8.1 缓冲区大小和周转时间
缓冲区周转时间是连续的 flits 可以重复使用缓冲区所间隔的最短空闲时间。缓冲区周转时间过长会导致缓冲区重用效率低下,从而导致网络吞吐量较差。如果实现的缓冲区数量没有覆盖缓冲区周转时间,则网络将在每个路由器处被人为地节流,因为即使没有来自路由器其他端口的争用,flit也无法连续流到下一个路由器(没有可用缓冲区而阻塞)。如图 5.10 所示,Credit计数在发送两个flit后变为0,无法继续发送flit。只能等待下游路由发送Credit更新后,才能继续发送。两个路由器之间的链路空闲 6 个周期,同时等待下游路由器的空闲缓冲区。
如图11所示,缓冲区周转时间至少是flit流水线延迟+flit传输延迟+credit传输延迟+credit处理延迟之和。
此处,缓冲器周转时间至少是开/关信号传播延迟的两倍加上数据片传播延迟和流水线延迟,如图 5.11b 所示。
如果我们对相邻节点之间的数据流和反向信令有 1 个周期的传播延迟,对缓冲区反压信号有 1 个周期的管道延迟,以及 3 个周期的路由器管道,那么基于信用的反压将有一个缓冲区周转时间至少 6 个周期,而开/关背压将具有至少 8 个周期的缓冲区周转时间。请注意,这意味着使用开/关背压的网络每个端口至少需要 8 个缓冲区来覆盖周转时间,而如果选择基于信用的背压,则每个端口需要的缓冲区少 2 个。因此,缓冲区周转时间也会影响区域开销,因为缓冲区占据了路由器占用空间的很大一部分。请注意,一旦确定 flit 将离开路由器并且不再需要其缓冲区,就可以通过触发反压信号(credits 或 on/off )来优化缓冲区周转时间。
5.8.2 反向信号线
虽然开/关反压与基于信用的反压相比表现较差,但它在反向信号线开销方面具有较低的开销。图 5.12 说明了两种反压机制所需的反向信号线数量:基于信用的要求每个队列(虚拟通道)有 logB 条线,其中 B 是队列中缓冲区的数量,用于对信用计数进行编码。另一方面,开/关每个队列只需要一根线。每个队列有八个缓冲区和两个虚拟通道,基于信用的背压需要六个反向信号线(图 5.12a),而开/关只需要两个反向线(图 5.12b)。在片上网络中,片上布线丰富,与区域开销和吞吐量相比,反向信号线开销往往不太受关注。因此,基于信用的背压将更合适。