AMBA CHI

1. CHI简介

        一致性集线器接口(CHI Coherent Hub Interface)是AXI一致性扩展(ACE)协议的演进。CHI适用于需要一致性的各种应用,包括移动、网络、汽车和数据中心。

        AMBA总线最常见的协议 – APB>AHB>AXI>ACE>CHI,它们的复杂度、性能和设计难度都是递增的。CHI协议是AMBA的第五代协议,可以说是ACE协议的进化版,将所有的信息传输采用包(packet)的形式来完成。但是从接口的角度看,CHI和ACE,AXI这些协议完全不一样了。

1.1 术语

术语描述
Transaction一个transaction执行一个单独的操作,如一个transaction可以是读memory或写memory
Message协议层术语,用于定义两个组件之间交换信息的粒度,如:RequestData responseSnoop request一个数据响应message可能由多个packets组成
Packet端到端跨越interconnect的传输粒度,一个message可能由一个或多个packets组成,每个packet包含有源和目的节点的ID来保证在interconnect上独立路由
Flit最小流控单位,一个packet可以由一个或多个flits组成,对于同一个packet的所有flits在interconnect上传输必须遵循同样的路径,对于CHI,所有的packets都是由一个flit组成
Phit物理层传输单位,一个flit可以由一个或多个phits组成,phit定义为两相邻网络设备之间的一个传输,对于CHI,所有的flits都是由一个phit组成
PoSPoint of Serialization,位于ICN内,用于Requests之间的保序(HNF同时具有PoS和PoC的功能)
PoCPoint of Coherence,一致性节点,用于保证所有访问同一个memory地址的请求都可以得到同一份数据
PoPPoint of Persistence(PoP)是内存系统中的一个点,当系统电源断开时,会保持对内存的写入,当电源恢复时,会可靠的恢复对内存的写入。
PoPAPoint of Physical Aliasing (PoPA),在一个物理地址空间(PAS)中的位置更新对所有其他物理地址空间可见。
Downstream cachedownstream cache是以RN的视角定义的,RN的downstream cache可以通过CHI请求访问
RequesterRequester可以指独立产生原始transactions的组件(master),也可以指ICN
CompleterCompleter可以指ICN,也可以是SN
Master通常是一个系统中最上游的agent
Slave通常是一个系统中最下游的agent
Endpointslave的另一个名字,指的是一个transaction的最终目的地
Protocol Credit一个P-credit用于保证completer有能力接收一个transaction
Link layer Credit一个L-credit用于保证另一边的link可以接受不了一个flit
ICNinterconnect的简称,用于协议节点之间的通讯的CHI传输机构,ICN可能也包含协议节点,如HN和MN
IPAintermediate Physical Address,中间物理地址,在两级地址系统中,第一级产生IPA,第二级产生物理地址
RN请求节点,产生协议transaction,包含读和写
HNHome节点,位于ICN,用于接收来自RN的协议transaction,完成相应的一致性操作并返回一个响应
SN从属节点,用于接收来自HN的请求,完成相应的操作并返回一个响应
MN其他节点,位于ICN,用于接收来自RN的DVM操作,完成相应的操作并返回一个响应
IO Coherent nodeIO一致性节点产生的snoop请求不会导致数据被cache,因此IO一致性节点也不会接收到任何snoop请求
snoopee正在接收snoop的RN。
Write-Invalidate protocol该协议是指当RN往一个共享地址写数据时,必须先把所有共享的数据备份都无效掉,然后再进行写操作,CHI采用的就是该协议
In a timely manner协议中没有定义在某个绝对的时间后,某件事必须发生,但是及时发生可以使系统效率更高
Don’t Care表示该域段可以设置为任何值,包括非法值和保留值,任何组件收到的包中如果包含设为Don’t care的域段,都必须忽略该域段
Inapplicable表示该域段值不会用于信息处理

1.2 组件名称

类别组件名
RN请求节点。生成到互连的协议事务,包括读取和写操作。请求节点被进一步分类为:
RN-F完全一致性请求节点:包含硬件一致性cache允许产生所有协议定义的transactions;支持所有的snoop transactions
RN-DIO一致性请求节点,支持DVM操作:不包含硬件一致性cache;可以接收DVM操作;可以产生协议定义的一部分transactions
RN-IIO一致性请求节点:不包含硬件一致性cache;不能接受DVM操作;可以产生一部分协议定义的transactions;不要求具有snoop功能
HNHome Node,位于从请求节点接收协议事务的互连器内的节点。主节点被进一步归类为:
HN-F用于接收所有的请求操作,除了DVM操作:POC点,通过监听RN-Fs,管理各Master一致性,完成所有的snoop响应后,发送一个响应给发出请求的RN;PoS点,用于管理多个memory请求的顺序;可能包含目录或监听过滤,以此来减少大量的snoop request
HN-I处理有限的一部分协议定义的Request请求:PoS点,管理访问IO subsystem的顺序;不包含PoC点,也不具备处理snoop请求
MN用于接收来自RN发送的DVM操作,完成相应的操作,并返回一个响应
SNSlave Node,用于接收来自HN的请求,完成相应的操作并返回一个响应;
SN-F指的是Normal memory,可以处理Non-snoop读写请求、atomic请求、以及这些命令的其它形式、CMO请求
SN-I指的是Peripheral或Normal Memory,可以处理Non-snoop读写、atomic操作、以及这些命令的其它形式、CMO请求


2. CHI介绍

        CHI 旨在实现可扩展性,能够构建小型、中型或大型系统。这些系统使用多个组件,范围从处理器集群、图形处理器和内存控制器,到 I/O 桥、PCI Express(PCIe)子系统和互联本身。

2.1 CHI 网络拓扑

        CHI 定义了 CHI 网络中的不同组件,但没有定义用于连接这些组件的拓扑。这种拓扑灵活性允许根据性能、功耗和面积要求驱动组件连接。拓扑有:

        • 环形拓扑:在环中,每个组件直接连接到另外两个组件,形成一个所有组件都可以相互通信的环。这种拓扑的缺点是延迟随环中组件数量的增加而线性增加。这是因为事务必须遍历环,直到到达目的地。因此,环形拓扑最适合中等规模的系统
        • 网格拓扑:与环相比,网格包含更多事务到达目的地的路径,因此减少了事务的传输时间。这提供了更高的系统带宽,但是占用了更多的面积网格拓扑最适合大规模系统
        • 交叉开关:这种拓扑允许每个节点连接到每个可能的节点。这种设计提供了最佳性能,因为每个组件都与需要通信的组件直接连接。这种拓扑的缺点是连接所有组件的成本。这是因为随着每个附加组件,系统所需的导线数量可能会显著增加。因此,交叉开关最适合小型系统

        在此图中,圆圈表示网络中的请求者和从组件。方形表示用于在请求者和从端之间路由事务的中间组件。

2.2 CHI 协议迭代

        目前有六个版本的 CHI 协议:A 到 F。本文描述 A 到 C 的问题以及之间的主要差异。
        CHI-A 是 CHI 协议的第一个版本。它提供了一个传输层,具有减少拥塞的功能。描述了 CHI 的基本行为。此规范包括:
        • 新通道、CHI 术语和组件命名的定义
        • 请求、监听过滤器和缓存状态转换的示例
        • 事务排序、独占访问和分布式虚拟内存(DVM)操作的规则
        CHI-B 扩展了 CHI-A,但不能直接向后兼容 CHI-A。它添加了支持 Armv8.1 和 Armv8.2 系统扩展的功能,例如:
        • 更大的物理地址宽度
        • 原子事务
        • DVM 的 VMID 扩展
        • 通道字段、事务结构和可靠性、可用性和可维护性(RAS)特性的描述
        • 直接内存传输和直接缓存传输功能,减少内存和监听访问延迟
        CHI-C 是 CHI-B 的次要扩展。此扩展主要添加了减少请求危险生命周期的功能。CHI-C 还添加了两个操作码,以减少完成确认的时间,并对协议进行了更改以支持这些操作码。

2.3 CHI 缓存行状态

        CHI 使用了类似于 ACE 的一致性模型,增加了对监听过滤器和基于目录的系统的支持。CHI 还使用与 ACE 相同的术语来定义缓存状态,并添加了部分和空缓存行状态。
        • 有效和无效:用于描述缓存行是否存在于本地缓存中。
        • 如果缓存行有效,则必须是唯一或共享的:唯一意味着缓存行仅存在于此缓存中,而不在任何其他请求者本地缓存中。仅当缓存行处于唯一状态时,才能对本地缓存行进行存储。共享意味着缓存行存在于此缓存中,并且可能存在于其他请求者本地缓存中,也可能不存在。
        • 如果缓存行有效,它必须是Clean或Dirty的:Clean表示缓存不负责更新主内存。由于在另一个缓存中进行的先前更新,缓存行仍然可以保存与主内存不同的值。Dirty表示相对于主内存修改了缓存行。当此行从此缓存中逐出时,请求者必须确保更新主内存,或者将脏责任传递给系统中的另一个组件。
        • 一行可以处于部分和空状态:空缓存行没有有效的数据字节,但行的所有权仍然属于请求者。部分缓存行可以具有一些有效字节,包括无字节或所有字节。这是因为状态已更新,但尚未写入有效字节,或者因为已写入所有字节,但尚未更新状态。在此状态下监听缓存行时,可以给出的响应有额外的限制。

        无效(Invalid,对应I态):缓存行不在缓存中。
        唯一脏(Unique Dirty,对应M态):此缓存行仅存在于此缓存中,并相对于主内存进行了修改。在此状态下,请求者可以对缓存行执行写操作,因为该行已处于唯一状态。如果监听指示,缓存行必须转发给请求者。
        唯一脏部分(Unique Dirty Partial):此缓存行仅存在于此缓存中,并被认为相对于主内存进行了修改。它可以具有一些有效字节,其中一些包括无字节或所有字节。在此状态下,请求者可以对缓存行执行写操作,因为该行已处于唯一状态。对于监听,即使监听指示也不能将缓存行直接转发给原始请求者。
        共享脏(Shared Dirty,对应O态):相对于主内存修改了此缓存行,而且这个特定的缓存有责任更新主内存。由于缓存行是共享的,它可能存在于一个或多个本地缓存中,但这并不是必须的。如果该行存在于多个缓存中,这些缓存将在共享干净状态下拥有此行。
        唯一干净(Unique Clean,对应E态):与主内存相比,缓存行没有被修改,并且仅存在于单个本地缓存中。它可以在不通知其他缓存的情况下进行修改。
        唯一干净空(Unique Clean Empty):缓存行仅存在于此缓存中,但没有有效字节。缓存行可以在不通知其他缓存的情况下进行修改。如果监听请求该行,则不得将该行返回给Home或直接转发给原始请求者。
        共享干净(Shared Clean,对应S态):缓存行可能存在于一个或多个本地缓存中。与主内存相比,该行可能已被修改,但此缓存不负责在逐出时将行写回内存。


3. CHI协议基础

        CHI通过节点类型对系统中的不同组件进行分类,并提供了节点之间通信的方法。

3.1 节点

        主要有三种类型的节点:请求节点(RNs,生成事务,如读和写请求,这些事务发送到HNs)、基节点(HNs,负责对请求进行排序,向SNs生成事务,并可以发出监听或处理DVM操作)和从节点(SNs)。此外,还有杂项节点(MNs)。总结如下:

完全一致IO一致DVMMN
RN

一致性缓存

接受并响应监听

无一致性缓存

不接受或响应监听

在其他所有方面与RN-I相同
HN

对一致性内存的请求进行排序

向RN-Fs发送监听

对I/O子系统的请求进行排序处理由RN发送的DVM事务
SN连接支持一致性内存空间的存储器设备连接支持一致性内存空间的存储器设备

        • 请求者:是通过发出请求消息启动事务的组件。可用于独立发起事务的组件,也可用于互联组件,其发出下游请求消息,可独立或作为系统中正在发生的其他事务的副作用。

        • 完成者:是响应从其他组件接收到的事务的组件。可以是互联组件(如HN或MN),也可以是位于互联之外的组件(如从属组件)。

3.2 系统地址映射

        系统中的每个组件都被分配一个唯一的节点ID。CHI使用系统地址映射(SAM)将物理地址转换为目标节点ID。为了能够确定发出请求的目标节点ID,每个RN和HN都必须具有SAM。以下图示展示了RN SAM将物理地址映射到HN节点ID,以及HN SAM将物理地址映射到SN节点ID:

        RN SAM必须满足以下要求:

        • 它必须完全描述整个系统地址空间

        • 任何不对应于物理组件的物理地址必须映射到一个可以提供适当错误响应的节点

        • 所有RN必须对RN SAM有一致的视图。

3.3 节点通道

        与ACE相比,CHI使用不同的通道,TX通道用于发送消息,RX通道用于接收消息:

        • 请求(REQ):发送读和写请求、缓存维护请求和DVM请求

        • 响应(RSP):发送各种类型消息的完成响应,范围从写和缓存管理响应到无数据监听响应和操作完成确认。

        • 监听(SNP):发出监听或发送DVM操作数据传输消息和标记为DAT的,发送写和读数据,以及带数据的监听响应

        下图显示了RN-F上CHI请求者接口上的通道:

        当RN-F发出读请求时,它在其TXREQ通道上发送请求。当读数据返回时,RN-F在其RXDAT通道上接收数据。每个节点上的TX信号连接到目标节点上的RX信号。在SNP通道上以下约束:

        • 只有HN-F和MN在SNP通道上发出消息

        • RN-F仅在SNP通道上接受监听

        • MN仅在SNP通道上接受DVM消息监听

3.4 切片Flit

        所有协议消息都以Flit(切片)的形式发送。Flit是一种打包的控制字段和标识符集合,用于传递协议消息。在Flit中发送的一些控制字段包括操作码、内存属性、地址、数据和错误响应。每个通道需要不同的Flit控制字段。例如,请求通道上用于读或写的Flit需要一个地址字段,而数据通道上的Flit需要数据和字节使能字段。与PCIe或以太网协议中的字段不同,Flit中的字段不会在多个数据包上串行化。相反,它们是并行发送的。

        在CHI中传递Flit的握手机制与ACE中的不同。每个通道都关联有一个FLITV信号,发射器将该信号设置为高电平以表示Flit有效。然后在下一个上升CLK边沿上进行传输。只有当发射器先前收到接收器的信用LCRDV信号时,才能发送Flit。

        为了在Flit中提供额外的信息,CHI定义了多个标识符字段。例如:

        • 源ID字段(SrcID):用于路由Flit。该字段标识Flit的发送者,是发送消息的组件的节点ID。

        • 目标ID字段(TgtID):用于路由Flit。目标ID值是接收消息的节点的ID。除了监听Flit之外,每个Flit都包含目标ID字段。HN-F可以使用任何机制来路由监听,例如向所有RN-F广播监听,或使用监听过滤器仅针对RN-F的子集。无论使用什么机制,当监听Flit离开互连时,它已经针对特定节点。

        • 事务ID字段(TxnID):出现在每个Flit中。此字段是一个8位字段,用于标识源节点和目标节点之间的每个事务。来自RN的每个未完成请求都必须具有唯一的TxnID。在任何时候,RN最多可以有256个未完成的事务。

        • 请求操作码(Opcode):出现在REQ Flit中。这指定了事务类型,并且是决定事务结构的主要字段。例如,不同类型的读请求,写请求或无数据请求。

        • 数据缓冲区ID(DBID):仅出现在响应和数据Flits中。目标节点使用此标识符来表示接收写数据的可用性,并释放需要完成确认的事务。

        ◦ 对于写操作,请求者在收到完成者的响应中的DBID值之前不能发送写数据

        ◦ 一些读事务已完成确认结束,这是请求者表示已收到读数据的地方。将读数据发送回请求者时,数据flit包含一个DBID值,供请求者在发送完成确认消息时使用。

4. 事务流程

        事务是节点完成请求所需的系统消息集合。以下示例中,我们展示了在请求者和完成者之间的写请求中使用标识符。请求者被分配节点ID 1,完成者被分配节点ID 2。以下描述了事件顺序:

        1. 请求者向完成者发送具有事务ID(TxnID)3的写请求。请求者中的源ID(SrcID)字段填充了请求者的节点ID。目标ID(TgtID)字段填充了完成者的节点ID。此步骤如下图所示:

        2. 完成者将请求的事务ID和源ID分配给一个可用的数据缓冲槽。在本例中,请求被分配了数据缓冲区ID(DBID)0。

        3. 完成者向请求者发送带有TxnID 3和DBID值0的DBIDResp消息,如下图所示:

        4. 请求者使用接收到的DBID作为事务ID向完成者发送写数据。

        5. 当事务完成时,对应于DBID 0的缓冲槽将被释放。

4.1 ReadNoSnp事务流程

        以下示例展示了完成ReadNoSnp事务所需的消息序列。请求节点0发出ReadNoSnp请求,完成节点5提供读数据。以下描述了事件顺序:

1. 请求节点0向CHI互连发出一个ReadNoSnp,目标为Home节点3。该事务在请求者节点的TXREQ通道上发送。此步骤如下图所示:

2. 基节点3在其TXREQ通道上向完成节点5发出ReadNoSnp请求,以检索数据,如下图所示:

3. 完成节点5在其TXDAT通道上发出CompData响应,将数据返回给基节点3,如图所示:

4. 基节点3将CompData响应发送给请求节点0。请求节点0在RXDAT通道上接收数据,如图所示:

4.2 WriteNoSnp事务流程

        本节介绍了从请求节点0到完成节点5的WriteNoSnp事务的流程。以下描述了事件的顺序:

1. 请求节点0在TXREQ通道上向基节点3发送WriteNoSnp消息,如图所示:

2. 基节点3向请求节点0响应一个CompDBIDResp消息。此响应表明它可以接受写数据,并且WriteNoSnp对其他请求者是可观察的。此消息通过基节点的TXRSP通道发送。此步骤如下图所示:

3. 以下两个步骤可以按任意顺序发生:

(a)基节点3向完成节点5发出WriteNoSnp消息,并收到CompDBIDResp响应,如图所示:

(b)或者,请求节点0可以通过其TXDAT通道将WriteNoSnp的写数据发送到基节点3,如图所示:

4. 在收到来自完成节点的CompDBIDResp和来自请求节点的写数据后,基节点3在TXDAT通道上将写数据发送到完成节点5,如图所示:

4.3 完成确认

        CHI使用完成确认响应来维护以下事务的顺序:

        • 由完全一致请求节点(RN-F)发起的事务

        • 由这些RN-F事务引发的监听事务

        完成确认确保在一致事务完成后,按顺序在RN-F之后接收到监听事务。

        HN-F可以通过暂停事务来维护事务顺序。例如,RN-F可能已经有一个正在处理的针对特定缓存行的未完成事务。如果系统中的另一个请求者发起一个导致对同一行进行监听的事务,HN-F可以暂停这个后来的事务。当原始的RN-F完成一致事务时,RN-F使用其TXRSP通道向HN-F发送完成确认(CompAck)消息。然后,HN-F解除等待完成确认的监听阻塞。这种机制与ACE中的RACK/WACK功能类似。

        并非CHI中的每个事务都需要完成确认。请求Flit包含一个ExpCompAck字段,用于表示何时需要完成确认。如果需要完成确认,RN-F在请求中将ExpCompAck设置为1,并在请求完成时发出CompAck响应。流程如下:

  1. 请求节点(RN-F)发起一个具有ExpCompAck = 1的请求。
  2. 基节点完成请求。
  3. 基节点向RN-F发送Comp或CompData。
  4. RN-F向基节点发送CompAck。
  5. 基节点现在可以向RN-F发送等待中的监听。

        以下示例展示了在需要读请求中的完成确认时发送的消息:

1. 请求者向完成者发送一个读请求,请求地址为0x8000,ExpCompAck字段设置为1,如图所示:

2. 完成者为读地址分配一个任意的DBID位置,阻止互连发出针对将来一致请求的监听。这个位置如图所示:

3. 完成者使用CompData响应回应请求者,同时表示事务完成并发送读数据。响应中的DBID字段填充了用于存储读地址的DBID位置。这一步如下图所示:

4. 请求者发送一个CompAck消息。CompAck使用从完成者那里接收到的DBID值作为事务ID,如图所示:

完成者清除地址0x8000的DBID位置,允许互连向该位置发出未来的监听。

4.4 带有监听的CompAck

        本示例展示了在需要多个请求节点访问相同可缓存内存位置的完成确认时发送的消息。在此示例中,CHI互连向所有缓存请求者广播监听。或者,它可以使用监听过滤器并仅针对本地存在该行的请求者。以下列表描述了事件的顺序:

1. 请求者节点0向基节点3发送地址A的MakeUnique消息。当请求者节点0向基节点3发出完成确认时,此事务完成。这一步如下图所示:

2. 基节点3向请求者节点1和2发送地址A的SnpMakeInvalid监听,如图所示:

3. 请求者节点1和2以SnpResp_1响应。这些响应意味着地址A已失效。基节点3可以按任意顺序接收SnpResp_I。这一步如下图所示:

4. 请求者节点2向基节点3发送地址A的ReadShared请求。请注意,基节点3仍未对请求者节点0的MakeUnique消息作出回应。现在,直到请求者节点0发送MakeUnique的完成确认消息,由ReadShared请求生成的监听将被阻塞。这一步如下图所示:

  • 5. 由于在步骤3中收到的监听响应,基节点3向请求节点0发送Comp_UC消息。
  • 6. 请求节点0发送CompAck消息并解除对地址A的监听阻塞。
  • 7. 基节点3为地址A生成向请求节点0和1的SnpShared监听。
  • 8. 请求节点1以SnpResp响应,表示它没有数据。
  • 9. 请求节点0以SnpRespData响应,发送地址A的最新数据。基节点3可以按任意顺序接收这两个响应。
  • 10. 收到两个监听响应后,基节点3将监听数据返回给请求节点2。
  • 11. 请求节点2向基节点3发送完成确认。基节点3可以向地址A生成未来的监听。

4.5 CHI中的端点顺序和请求顺序

        事务可以按端点顺序和请求顺序排序,如下所述:

        • 端点顺序保持从单个请求者到单个从属地址范围的事务顺序。例如,在端点顺序中,向从属的可编程寄存器组发出多个设备访问。

        • 请求顺序保持来自单个请求者到同一地址的事务顺序。例如,当向重叠的非缓存地址(如Normal NC、Device-GRE和Device-nGRE)发出多个请求时,需要排序。当设置请求顺序时,CHI不要求地址匹配的精确粒度,粒度由实现定义。

        注:如果设置端点顺序,请求顺序是隐含的。请求Flit中的Order字段控制排序类型。只有一些请求类型可以使用请求顺序和端点顺序。这些请求类型是:

• ReadNoSnp和任何ReadOnce类型的请求:

◦ 请求者发出需要排序的ReadNoSnp或ReadOnce类型请求

◦ 从属接受请求并以ReadReceipt消息回应。ReadReceipt信号表明可以发出下一个有序请求

◦ 通过发出ReadReceipt响应,从属保证按收到的顺序维护请求

• WriteNoSnp和WriteUnique类型的请求:

◦ 请求者发出需要排序的WriteNoSnp或WriteUnique类型请求

◦ 从属以DBIDResp消息回应以表示可以接受消息。DBIDResp响应表示数据缓冲区插槽可用于接受写数据,并且请求者可以发出下一个有序请求。

◦ 通过发出DBIDResp,从属保证按收到的顺序维护请求

事件顺序如下:

  1. 请求者使用ReqOrder设置向从属发起读请求1。
  2. 请求者向从属发出带有ReqOrder设置的读请求2,但由于请求1仍未完成,请求者被阻止发送请求。
  3. 从属以ReadReceipt消息回应读请求1,表示请求已被接受。
  4. 以任意顺序:
  5. 请求者向从属发送读请求2。
  6. 从属将读请求1的读数据返回给请求者。

4.6 请求重试

        有时目标节点可能没有足够的资源来接受请求。为防止在资源不可用时阻塞请求通道,CHI提供了一个请求重试机制。请求重试机制使用协议信用(Protocol Credits)来指示资源可用性。确定和记录处理请求所需的协议信用(PCrd)类型是从节点的责任。

        该机制可以使用不同类型的协议信用来跟踪不同的资源。例如,读请求和写请求可以使用单独的数据缓冲区,因此每个缓冲区可以使用不同类型的协议信用来指示可用性。不同类型的协议信用值由实现定义。

        以下示例描述了伴随请求重试发送的消息序列。在此示例中,请求者节点1发出请求,因为完成者无法接受请求。以下描述了事件顺序:

        1. 每个请求最初都是在没有协议信用的情况下发出的。请求Flit中有一个名为AllowRetry的控制字段。第一次发送请求时将此字段设置为YES表示请求没有使用协议信用。当AllowRetry为YES时,请求中的PCrdType字段必须为0。以下图表显示了请求设置:

        2. 在示例中,目标节点由于请求缓冲区已满而无法接受请求,因此返回一个RetryAck消息。

        3. RetryAck响应Flit中设置了一个PCrdType字段,其值表示需要重试请求所需的信用类型。在此示例中,PCrdType的值为2,如图所示:

        4. 当目标节点可以接受请求时,它在RSP通道上发送一个PCrdGrant消息。PCrdGrant响应Flit使用PCrdType字段来指示已变为可用的协议信用类型。请求者只有在PCrdGrant消息和RetryAck响应中的协议信用类型匹配时才能重试请求。在这个例子中,两个字段都必须设置为2。如果协议信用类型匹配,目标节点现在可以保证接受请求。

        5. 请求者重新发出请求,并将AllowRetry字段设置为0。将AllowRetry字段设置为0表示向目标节点指示请求正在使用已授予的协议信用。

5. DVM操作

        与ACE一样,CHI支持分布式虚拟内存(DVM)操作。DVM请求传递操作以支持维护虚拟内存系统。

5.1 DVM操作事务

        CHI使用DVM操作来管理虚拟内存。DVM操作执行以下事务:

• 事务查找边缘缓冲器(TLB)失效

• 指令缓存失效

• 分支预测器失效

• DVM同步

        在CHI中,所有DVM操作都分为两部分发送到MN。这与ACE不同,在ACE中,一些DVM操作需要两部分,而其他操作只需要一部分。以下列表描述了CHI中的部分顺序:

• DVM操作的第一部分作为请求发送给MN,Opcode字段设置为DVMOp。请求Flit使用地址字段来编码操作的属性。

• DVM的第二部分作为数据Flit发送,只有在请求节点收到MN的DBID响应后才发送。这第二部分携带了DVM操作所针对的地址。

        当MN收到DVM操作的两个部分时,MN会向参与一致性域的请求节点生成DVM Snoop。MN在节点监听通道上发送两部分的DVM Snoop。DVM Snoop的两个部分必须使用相同的TxnID和Opcode SnpDVMOp,并使用以下参数:

• 第一部分使用地址字段来编码操作属性和目标地址的高位

• 第二部分使用地址字段发送地址的其余位

        为了区分这两部分,CHI要求地址字段的bit[3]设置为0以表示第一部分,设置为1表示第二部分。DVM监听的第二部分可能在第一部分之前到达RN。

5.2 DVM操作类型

        CHI定义了两种类型的DVM操作:非同步DVM(DVM Non-Sync)和同步DVM(DVM Sync)。DVM操作的属性决定了RN在响应DVM Snoop之前是否必须等待操作完成。

        同步DVM仅执行同步操作,没有其他操作。

        非同步DVM是TLB、指令缓存和分支预测器的失效操作。非同步DVM不需要在发出更多DVM操作之前完成DVM操作的执行。这允许有多个非同步DVM未完成。

        在以下示例中,RN-F可以发出多个分支预测器或指令缓存失效,接收RN-F或RN-D不必立即执行操作:

  1. RN-F或RN-D接收到一个指示DVM Non-Sync的DVM Snoop。
  2. RN-F或RN-D向MN发出Snoop响应。Snoop响应确认收到DVM消息,但不表示请求节点已经执行了DVM操作。
  3. MN向发起RN-F发送完成消息,表示已接受DVM操作。

        为确保所有未完成的DVM请求已执行,需要执行以下步骤:

  1. RN-F向MN发出同步DVM操作,也称为DVM Sync。需要在发出DVM Sync之前接收完成响应的任何DVM请求都必须先完成。
  2. MN在监听通道上向所有RN-F和RN-D发出DVM Sync。
  3. 每个目标RN确保其所有未完成的DVM操作已执行。
  4. 每个RN向MN发出一个Snoop响应,表示所有操作已执行。
  5. MN向最初发出同步DVM操作的RN-F发送DVM Sync的完成响应。

        CHI DVM Sync与ACE中的DVM Sync类似。两者都检查之前发出的DVM操作是否已完成。不同之处在于,CHI不需要DVM完成消息。

5.3 DVM操作流程

        本节描述了一个TLB失效DVM请求,后续有一个同步DVM操作,并展示了以下事件:

• DVM请求的不同部分

• MN生成的监听操作

• DVM同步如何确保之前的DVM操作已执行

        事件顺序如下:

  1. 请求节点0向MN发出一个TLB失效DVM请求。
  2. MN用DBIDResp消息响应,表示可以接受DVM请求的第二部分。
  3. 请求节点0向MN发出写数据消息。这是DVM消息的第二部分。
  4. MN将DVM请求的两个部分发送给请求节点1。
  5. 请求节点1通过向MN发送监听响应来确认DVM请求。
  6. MN接收到监听响应。
  7. MN向请求节点0发出完成消息。
  8. 请求节点0向MN发出一个DVM同步操作。
  9. MN向请求节点0发出DBIDResp消息。
  10. 请求节点0向MN发送写数据消息。这是DVM同步消息的第二部分。
  11. MN向请求节点1发出DVM同步监听操作。
  12. 请求节点1完成所有未完成的DVM操作。
  13. 请求节点1向MN发送监听响应,表示已完成所有操作。
  14. MN向请求节点0发出完成消息。这是对DVM同步请求的响应。

6.缓存贮存(stashing)

        缓存贮存是一种在系统内特定缓存中安装数据的机制。CHI-B引入了这个特性以提高系统性能。缓存贮存机制通过在数据即将使用的地方附近分配一个缓存行来提高系统性能。当使用数据时,这将导致更低的内存访问延迟。

        通常,缓存贮存(Stash)请求由RN-I和RN-D节点发起。缓存贮存请求是一个建议,而不是一个强制性动作。接收缓存贮存请求的设备可以忽略该请求。

        CHI支持两种主要形式的缓存贮存:包含写数据的贮存事务,以及无数据的贮存事务。两种形式的缓存贮存都可以将不同的缓存级别作为贮存目标。缓存贮存支持已添加到ACE5-Lite协议中。CHI协议在缓存贮存方面非常灵活,允许贮存请求采用多种形式。

6.1 事务流程

        缓存贮存的基本事务流程如下:

  1. RN在请求通道上发起一个缓存贮存请求。
  2. 缓存贮存请求被转发给HN-F。
  3. HN-F可以:
    • 忽略缓存贮存请求。RN-F将贮存监听视为非贮存版本并做出相应的响应。或者,
    • 接受请求并生成针对RN-F的监听。RN-F响应并将缓存行提取到其缓存中。
  4. 被指定进行贮存的RN-F接收到一种特殊类型的noop请求,称为贮存监听。

RN-F可以:

• 使用DataPull机制提供一个充当关联缓存行读请求的监听响应

• 在不使用DataPull的情况下提供监听响应,然后为该缓存行发出独立的读请求

• 在不获取该行的情况下提供监听响应,忽略缓存贮存暗示

6.2 贮存监听请求

        所有缓存贮存请求都会发送到HN-F节点。当HN-F处理缓存贮存请求时,它会向目标RN-F生成贮存监听。CHI定义了四种不同的贮存监听请求,每种请求对应于初始缓存贮存事务。以下表格详细介绍了这些请求:

贮存缓存事务HN-F发出的监听请求RN-F采取的操作
WriteUniquePtlStashSnpUniqueStash使缓存行无效并返回数据(如果数据已更改,则带有写数据)
WriteUniqueFullStashSnpMakeInvalidStash如果存在,则使缓存行无效(带有写数据)
StashOnceSharedSnpStashShared针对缓存行发出共享请求(无数据)
StashOnceUniqueSnpStashUnique针对缓存行发出唯一请求,为未来写做准备(无数据)

6.3 缓存贮存控制字段

        CHI为缓存贮存添加了请求、监听、响应和数据Flit的控制字段。这些字段表示:

• 贮存目标的NodeID

• RN-F内的特定逻辑处理器缓存,如L2缓存

• 是否使用DataPull机制

        Request Flit对于缓存贮存请求使用以下字段:

• StashNID保存贮存目标的节点ID。如果RN-F被选为贮存目标,StashNID字段将填充RN-F的节点ID。

• StashNIDValid。如果在贮存时应使用StashNID字段,StashNIDValid将为1。

• StashLPID指定RN-F内的逻辑处理器ID。此字段允许将较低级别的缓存(如L2缓存)指定为贮存目标。

• StashLPIDValid。如果在贮存时应使用StashLPID字段,StashLPIDValid将为1。

        Snoop Flit还包含以下字段:

• StashLPID和StashLPIDValid。如果缓存贮存请求指示StashLPID有效(StashLPIDValid = 1),监听将使用缓存状态请求中的StashLPID值。如果没有指定StashLPID(StashLPIDValid = 0),则贮存的数据可以放置在RN-F内的共享缓存中。

• DoNotDataPull:如果此字段设置为1,则贮存目标无法请求DataPull,因此无法使用DataPull机制。

6.4 带写数据的事务

        如果请求者正在写入新数据并需要一个目标来存储该数据,则发出WriteUniqueStash事务。写入的数据可以是完整或部分缓存行。CHI使用以下操作码之一来指示带有贮存暗示的写:

• WriteUniquePtlStash表示部分缓存行写

• WriteUniqueFullStash表示完整缓存行写

        本节介绍I/O请求者如何发出带有写数据的贮存暗示。贮存事务的目标是系统中的RN-F。事件顺序如下:

1. RN-I发出带有写数据的WriteUniqueFullStash请求。为简化起见,此示例未描述HN-F的DBIDResp。如下图所示:

2. HN-F接受贮存请求,然后向RN-F发出SnpMakeInvalidStash请求,如下图所示:

  • 3. RN-F接收到NH-F的监听。
  • 4. RN-F接受贮存暗示并发出监听响应,如图所示:
  • 5. 如果使用DataPull机制,RN-F发出隐式读请求的监听响应,或者发出监听响应和单独的读请求。为简化起见,本示例中使用隐式监听响应和读请求,但未使用完整的DataPull流程。
  • 6. HN-F将从RN-I接收到的写数据发送给RN-F

6.5 无写数据的事务

        请求方在将缓存用作贮存目标但不写入数据时,使用无数据贮存事务。CHI对于无数据贮存请求使用以下操作码:

• 如果预期贮存目标会读取缓存行,则发出StashOnceShared。此操作码表示在分配后,缓存行应处于共享状态。

• 如果预期贮存目标会写入缓存行,则发出StashOnceUnique。此操作码表示缓存行应处于唯一状态,从而使贮存目标在将来需要时能立即写入缓存行。

        以下示例描述了没有写数据的贮存暗示。RN-I向RN-F发送贮存请求,将RN-F作为贮存目标,并且HN-F和RN-F都接受贮存暗示。

事件顺序如下:

1. RN-I向HN-F发出StashOnceUnique请求,指示RN-F是目标且没有写数据。以下图示显示了这个步骤:

2. HN-F接受贮存请求。

3. HN-F向主内存发出ReadNoSnp请求以获取缓存行,并向RN-F发出 SnpStashUnique 监听,如图所示:

4. 主内存将缓存行返回给HN-F,如图所示:

5. RN-F对监听作出回应,请求缓存行。

6. HN-F将缓存行转发给RN-F。

        贮存请求不需要有效的贮存目标。如果未指定贮存目标,则请求中的目标HN-F成为贮存目标。然后,HN-F选择是否将缓存行分配到其缓存中。以下步骤描述了无写数据的贮存暗示,目标是系统缓存。事件的顺序如下:

  1. RN-I向HN-F发出StashOnceShared请求。将StashNIDValid字段设置为0以定位HN-F。
  2. HN-F向主内存发出ReadNoSnp请求以获取指定的缓存行。
  3. 主内存将缓存行返回给HN-F。
  4. HN-F将缓存行分配到其缓存中。

6.6 DataPull机制

        DataPull机制是通过Snoop响应暗示读请求的一种方式,因此不需要单独的读请求来获取要贮存的缓存行。DataPull仅适用于贮存Snoop请求,而不适用于其他任何snoop。

        接收要求DataPull的请求的RN-F可以选择是否使用DataPull或发送单独的读请求。如果RN-F选择不请求DataPull,它会响应snoop,然后可以稍后发送读请求以获取缓存行。在本节中,我们描述了RF-F利用DataPull机制作为贮存事务的一部分接收数据的过程。DataPull的完整事务流程如下:

  1. HN-F发出贮存Snoop并将Snoop Flit中的DoNotDataPull字段设置为0。这表明RN-F贮存目标可以请求DataPull。
  2. 接收到DoNotDataPull = 0的RN-F可以选择在其Snoop响应中请求DataPull。在此示例中,RN-F选择请求DataPull。
  3. RN-F通过在Response Flit中设置两个字段来请求DataPull:
    • 将DataPull字段设置为1
    • 使用将用于返回读数据的TxnID填充DBID字段
  4. RN-F接收到读取的数据。
  5. RN-F向HN-F发送CompAck消息。

        以下图示显示了StashOnceUnique事务的DataPull机制的时序:

在此图示中,示例系统包含:

• 发起请求的一个RN-D

• 一个作为贮存目标的RN-F

• 一个HN-F

• 一个SN-F

示例中的完整事务流程如下:

  1. RN-D向HN-F发出StashOnceUnique请求。StashNID字段的值表示RN-F1是贮存目标。
  2. HN-F接受贮存请求。
  3. HN-F发出:
    • 一个ReadNoSnp请求到SN-F
    • 一个SnpStashUnique Snoop到RN-F1
  4. HN-F向RN-D发送完成响应。
  5. RN-F1接受贮存暗示。
  6. RN-F1使用SnpResp_I_Read DataPull请求响应SnpStashUnique。SnpResp_I_Read响应表示隐式读请求。DBID字段将事务ID设置为Y。
  7. SN-F将缓存行返回给HN-F。
  8. HN-F将缓存行转发给RN-F1,其中:
    • TxnID = Y
    • DBID = Z
  9. RN-F1向HN-F发出完成确认响应,TxnID = Z。

下一个示例显示了WriteUniquePtlStash事务的DataPull机制的时序:

在此示例中,系统具有:

• 一个RN-D节点

• 两个RN-F节点:RN-F1和RN-F2。当发送贮存请求时,RN-F2持有缓存行。

• 一个HN-F节点

示例中的事务流程如下:

  1. RN-D向HN-F发出WriteUniquePtlStash请求。贮存目标是RN-F1。
  2. HN-F接受贮存请求。
  3. HN-F向RN-D返回DBIDResp。
  4. HN-F生成一个SnpCleanInvalid Snoop到RN-F2。这是因为RN-F2持有缓存行,并将SnpUniqueStash发送到贮存目标RN-F1。
  5. RN-F2使缓存行无效。
  6. RN-F2返回一个带有Dirty数据的Snoop响应给HN-F。
  7. RN-F1发出一个带有隐式读请求的Snoop响应。DBID字段将贮存数据的TxnID设置为Y。
  8. HN-F接收到Snoop响应。
  9. HN-F向RN-D发出完成响应。
  10. RN-D将贮存请求的写数据发送给HN-F。HN-F现在同时拥有写数据和Snoop响应中的数据。HN-F为缓存行创建新数据。
  11. NH-F将缓存行的所有权发送给RN-F1。响应字段为:
    • TxnID = Y
    • DBID = Z
  12. RN-F1发送一个带有TxnID = Z的CompAck响应。

7. I/O释放(Deallocation)

        CHI-B为I/O请求者提供了在完全一致节点中释放(重分配)缓存行的能力。I/O释放事务提供了一个暗示,即应该使缓存行无效,并且脏数据应该写回到内存或被丢弃。因为这些请求仅仅是暗示,一个完全一致节点可以选择不使缓存行无效,而只是将数据返回给I/O请求者。换句话说,如果忽略了使缓存行无效的暗示,这些请求将被视为普通的ReadOnce事务。因为它们可以被忽略,I/O释放请求不是缓存维护操作的替代品。

        CHI为I/O释放定义了两种请求类型:ReadOnceCleanInvalid和ReadOnceMakeInvalid。这两种请求都有助于避免缓存污染,因为在不久的将来不再使用这些数据。这两种请求类型的区别在于,ReadOnceMakeInvalid不需要将脏数据写入到下一级内存,这可能导致系统中的脏数据被丢弃。这意味着在使用这种类型的请求时必须谨慎。

7.1 I/O释放事务示例

        本节描述了两个事务流程的示例。第一个示例使用ReadOnceCleanInvalid并将脏数据写回主内存。第二个示例使用ReadOnceMakeInvalid并丢弃脏数据。这两个示例中的系统都有:

• 完全一致请求节点(RN-F)设备。RN-F以脏状态持有请求的缓存行

• I/O一致请求节点(RN-I)设备

• CHI互连

• 主存

        在第一个示例中,ReadOnceCleanInvalid事务流程读取数据使其无效,并将其写回主存。此示例的完整事务如下:

  • 1. RN-I向HN-F发出ReadOnceCleanInvalid事务,如图所示:
  • 2. HN-F向RN-F发送SnpUnique请求,请求缓存行,如下图所示:

3. RN-F使缓存行无效并将脏数据发送到HN-F。

4. HN-F将数据返回给RN-I并将数据写入主内存,使其保持干净状态。

        在第二个示例中,ReadOnceMakeInvalid事务读取数据并使RN-F中的缓存行无效,但是并没有将脏数据写入主内存,而是丢弃了数据。此示例的完整事务流程如下:

1. RN-I向HN-F发出ReadOnceMakeInvalid事务,如图所示:

2. HN-F向RN-F发送SnpUnique请求,请求缓存行,如下图所示:

3. RN-F使缓存行无效并将脏数据发送到HN-F。

4. HN-F将数据返回给RN-I,然后丢弃脏数据。

        注:如果在代理读取已失效的脏缓存行之前将其覆盖,ReadOnceMakeInvalid请求可能导致数据丢失。仅在您知道将来不再使用此数据时才使用此事务。

8. DMT、DCT和PrefetchTgt

        在CHI-A中,读数据和Snoop数据都通过Home Node传输,然后发起请求的节点才接收到它。通过Home Node的传输增加了这些请求的访问延迟。为了减少这种延迟,CHI-B增加了直接内存传输(DMT)直接缓存传输(DCT)机制。下表总结了CHI-A和CHI-B中从SN或RN到RN的数据传输差异:

SN到RNRN到RN
CHI-A从SN读取的数据必须在返回RN的途中经过HN从RN获取的Snoop数据必须在返回RN的途中经过HN
CHI-B直接内存传输(DMT):SN数据绕过HN,直接传输到RN直接缓存传输(DCT):RN数据绕过HN,直接传输到RN

        为了支持DMT和DCT操作,在请求、Snoop和数据flit中添加了额外的标识符。这些额外的字段指定了以下信息,以便正确地将数据和任何需要的响应路由到正确的端点:

• 读数据的最终目标

• 原始请求的TxnID

• 向SN-F发出请求的HN,或者向RN-F发出Snoop的HN。HN仍然需要CompAck通知,说明DMT或DCT已完成。

        CHI-B问题还增加了Prefetch Target(PrefetchTgt)事务,以减少内存访问的访问延迟。PrefetchTgt事务直接从RN-F发送到SN-F,不需要返回任何数据。存储器控制器可以将此作为提示,并为PrefetchTgt请求缓冲数据。如果在数据位于缓冲区时收到对该数据的普通请求,缓冲区将提供更快的访问时间。

8.1 直接内存传输(DMT)

        在以下示例中,您可以比较读请求在有DMT和没有DMT的情况下,读取数据所采取的路径。对于没有DMT的读请求,事务流程如下:

1. CPU向HN-F发出读请求,如图所示:

2. HN-F在地址上发生缓存未命中,并向内存控制器发出读请求,如下图所示:

3. 内存控制器获取读请求的数据,然后将数据发送回HN-F。

4. HN-F将读取的数据返回给请求缓存行的CPU。在到达目的地之前,读取的数据需要返回到HN-F。

        在第二个示例中,使用了DMT,事务流程修改如下:

1. CPU向HN-F发出读请求,如图所示:

2. HN-F在地址上发生缓存未命中,并向内存控制器发出读请求,如下图所示:

3. 内存控制器获取读请求的数据

4. 内存控制器将数据发送到发起CPU,而不是HN-F

        使用DMT时,读取的数据绕过HN-F,直接发送给发出读请求的CPU。大多数读请求都可以使用DMT机制,包括由缓存存储操作产生的隐式DataPull读。不能使用DMT的请求包括

• 独占访问

• ReadNoSnp 请求,其中 ExpCompAck = 0 且 Order != 0

• ReadOnce 请求,其中 ExpCompAck = 0 且 Order != 0

        为了支持DMT,CHI包含以下标识符字段:

• 请求Flit使用返回节点ID(ReturnNID)和返回事务ID(ReturnTxnID)字段

• 数据Flit使用基节点ID(HomeNID)字段

        下面的示例中的图示显示了DMT事务流程的时序,重点关注标识符字段的使用:

在此示例系统中有:

• 具有节点ID 1的RN-F(RN-F_NID1)

• 具有节点ID 2的HN-F(HN-F_NID2)

• 具有节点ID 3的SN-F(SN-F_NID3)

示例中的DMT事务流程以如下方式使用标识符字段:

• RN-F向HN-F发送具有TxnID = A和ExpCompAck = 1的ReadOnce请求

• HN-F的缓存中没有请求的数据,因此它向SN-F发出ReadNoSnp请求。ReadNoSnp请求包括:

◦ TxnID = B

◦ ReturnNID = 1。这表示应将读取的数据发送到具有节点 ID 1 的 RN-F

◦ ReturnTxnID = A。这与原始 ReadOnce 请求的 TxnID 匹配。

• 当SN-F准备好返回读取的数据时,它发送带有以下内容的CompData_UC消息:

◦ TxnID = A。这与SN-F收到的ReturnTxnID的值匹配

◦ HomeNID = 2。这是HN-F的节点 ID

◦ DBID = B。这与HN-F发送的ReadNoSnp的TxnID匹配

• RN-F向HN-F发送具有TxnID = B的CompAck消息。这与CompData_UC消息中的DBID字段匹配。

• HN-F收到CompAck后,可以停止跟踪它发送给SN-F的ReadNoSnp消息。

        在 CHI-B 中,针对某些 ReadOnce 和 ReadNoSnp 事务,包含了一种优化的 DMT 序列。该序列要求 SN-F 节点识别请求 Order 字段中的值 0x1,并向 HN-F 发送 ReadReceipt 响应。此项新增功能可减少 HN-F 节点处事务的生命周期,从而有可能释放资源。

        相比之下,CHI-A 在 Order 字段中将值 0x1 标记为保留,并且不要求 SN-F 提供 ReadReceipt。允许发送 ReadReceipt 响应的唯一节点是 HN 至 RN 和 SN-I 至 HN-I。

        下图显示了一个 ReadOnce 事务的优化 DMT 序列示例,其中 HN-F 缓存中没有请求的地址:

        在此示例中,事务流程如下:

  1. RN-F向HN-F发出TxnID = A的ReadOnce请求。
  2. HN-F向SN-F发出具有以下内容的ReadNoSnp请求:
    • Order = 0x01
    • TxnID = B
  3. ReturnNID 字段获取RN-F的节点ID。
  4. ReturnTxnID字段获取原始ReadOnce请求的TxnID。
  5. SN-F接受事务。
  6. SN-F向HN-F发出ReadReceipt。
  7. 当数据准备好时,SN-F使用原始TxnID将读数据发送到RN-F。

        HN-F 收到 Read Receipt 后,立即取消分配请求。这种取消分配减少了 HN-F 处事务的生命周期,并释放了资源。如果这是 CHI-A,那么 HN-F 需要等待从 RN-F 收到 CompAck 响应,然后才能停止跟踪 ReadNoSnp 事务。

8.2 预取目标(PrefetchTgt)

        为了进一步增强直接内存传输,CHI-B提供了预取目标(PrefetchTgt)请求,以减少SN-F处内存访问延迟。PrefetchTgt消息是从RN直接发送到SN-F的提示。该请求不需要响应,因此RN不会将其作为未完成请求进行跟踪。

        SN-F可以选择忽略请求,或者获取指定地址的数据。如果SN-F决定获取数据,它会将数据缓冲,直到收到该地址的正常读请求。假设在不久的将来,通过完全相干家节点HN-F的正常路径上会有一个单独的读事务。

        在SN-F处对数据进行缓冲可减少读事务的内存访问延迟,并隐藏HN-F系统缓存中首先进行的本地查找的任何额外延迟。

        由于不需要响应,PrefetchTgt中的TxnID字段不适用,CHI-B要求在发送请求时将其设置为0。例如,RN向SN-F发出请求。这是完成PrefectTgt事务所需的唯一步骤,双方都不会发送其他Flit。

        PrefetchTgt请求可能会提前很长时间发送,以至于SN-F会将缓冲数据驱逐出去,为其他读请求腾出空间。为了避免PrefetchTgt请求造成拥塞,CHI-B使用Data Flit中的DataSource字段来报告使用PrefetchTgt的有效性。此字段由内存控制器设置,表示读取的数据是否受益于之前的PrefetchTgt提示。DataSource字段可能的值为:

• 0x6表示PrefetchTgt请求有用

• 0x7表示读取的数据未从PrefetchTgt中受益,且无效

        如果足够多的PrefetchTgt请求被确定为无效,RN可以停止发出这些请求。通常,RN只实现RN系统地址映射(RN SAM)。此SAM针对HN-F,且不知道SN-F节点ID。为了支持PrefetchTgt事务,RN也需要HN系统地址映射。HN SAM将地址转换为SN-F TgtID。

        例如,PrefetchTgt提示可以优化DMT。CPU在DMT读取未命中之前发出PrefetchTgt请求。在PrefetchTgt事务之后,当DDR控制器收到读请求时,已经准备好读数据。示例中的完整流程如下:

  1. CPU向DDR控制器发出PrefetchTgt提示。
  2. DDR控制器接受提示并开始检索数据的过程。
  3. 两件事情并行发生:
    • CPU向HN-F发出与PrefetchTgt相同地址的读请求。
    • DDR控制器开始接收读数据并将其缓冲,以备后续读取。
  4. CPU向HN-F发出读请求
  5. 读请求在HN-F处导致缓存未命中。
  6. HN-F向DDR内存发出读请求。
  7. 由于数据已经在DDR控制器处缓冲,DDR立即将读取的数据返回给CPU。通过使用PrefetchTgt请求,DMT读事务在DDR内存访问中几乎没有延迟。

8.3 直接缓存传输(DCT)

        为了减少监听命中延迟,CHI-B使用直接缓存传输机制(DCT)。DCT类似于对监听的DMT,并允许从RN-F的监听数据绕过HN-F,直接到达原始请求者。当数据需要在请求者之间来回传输时,此机制有助于提高系统性能。

        受益于DCT的用例包括信号量(semaphores)和生产者-消费者工作负载。例如,您可以比较读请求在使用和不使用DCT的情况下读数据的路径。在没有DCT的情况下,整个系统级流程如下:

  1. CPU A向HN-F发出读请求。
  2. 该请求在HN-F处导致缓存未命中。
  3. HN-F向CPU B发出监听,后者持有缓存行。
  4. CPU B将缓存行的数据返回给HN-F。
  5. HN-F将数据返回给最初请求它的CPU A。

        使用相同的初始事务并添加DCT,整个系统级流程进行如下优化:

  1. CPU A向HN-F发出读请求。
  2. 该请求在HN-F处导致缓存未命中。
  3. HN-F向CPU B发出监听,后者持有缓存行。
  4. CPU B绕过HN-F,直接将数据返回给发出读请求的CPU A。

        通过使用DCT,监听命中的访问延迟得到降低。

8.4 转发监听请求

        为了支持DCT,CHI-B添加的元素之一是转发监听请求。转发监听请求告诉被监听的RN-F将监听数据直接发送到原始请求者。除了原子事务和独占读取外,所有可监听的读都可以使用DCT。转发类型的监听在监听Flit中引入了新的标识符字段,如下所示:

• 转发节点ID(FwdNID),其功能类似于DMT中的ReturnNID。它保存原始请求者的节点ID。

• 转发事务ID(FwdTxnID),其功能类似于DMT中的ReturnTxnID。它保存原始读请求的TxnID。

• 返回源(RetToSrc)指示RN-F将监听数据发送到HN-F,此外还要发送给请求的RN-F。将数据发送到RN-F可以使将来针对该地址的请求在HN-F缓存中命中,并避免产生额外的监听。

        在响应转发监听时,响应和数据Flit都使用新的转发状态(FwdState)字段。该字段告诉HN-F在任何本地监听过滤器跟踪中,向请求RN-F提供了什么缓存状态。被监听的RN-F中的缓存状态,即转发监听的结果,会像往常一样在RESP字段中提供给请求RN-F。原始请求者会在CompData消息中接收到监听数据,作为正常的读数据响应,如下图所示:

        在此图中,响应包含与DMT响应相同的HomeNID和DBID字段:

• HomeNID字段包含被绕过的HN-F的节点ID

• DBID字段包含转发监听的TxnID

        然后,RN-F将这些字段用作发送给HN-F的CompAck响应的TgtID和TxnID。以下两个示例展示了当RetToSrc设置为0或1时,标识符字段如何填充。这些示例中的系统具有:

• 两个具有节点ID 1和2(RN-F_NID1和RN-F_NID2)的RN-F

• 在两个实例中,RN-F2都在其缓存中保存了所请求的地址

• 一个具有节点ID 3的HN-F

        以下图示显示了当RetToSrc = 0时,DCT的事务流程:

在此图中,事务流程如下:

  1. RN-F_NID1向HN-F发出ReadNotSharedDirty请求。该请求具有TxnID = A。
  2. 该请求在HN-F处导致缓存未命中。
  3. HN-F向RN-F_NID2发出SnpNotSharedDirtyFwd监听。
    监听具有:
    • TxnID = B
    • FwdNID = 1。该值与RN-F_NID1的节点ID匹配。表示它是监听数据的目的地。
    • FwdTxnID = A。该值与读请求的原始TxnID匹配。
    • RetToSrc = 0
  4. 由于请求中的RetToSrc设置为0,RN-F_NID2使用SnpRespFwded消息回应HN-F。此响应中有两个重要字段:
    • RESP显示缓存行从UC状态转移到SC状态
    • FwdState告诉HN-F发送给原始请求者的缓存状态。在此示例中,即SC状态。
  5. RN-F_NID2向RN-F_NID1发送CompData消息,其中包括:
    • TxnID = A。这是监听请求中的FwdTxnID值。
    • HomeNID = 3。这是HN-F的节点ID。
    • DBID = B。这是监听请求的TxnID
    • RESP = SC(Shared Clean)。这显示了数据以SC状态提供,与监听响应中的FwdState字段值相匹配。
  6. RN-F_NID1向HN-F发送CompAck消息,TxnID = B。这完成了ReadNotSharedDirty请求。

        下面的图示中的第二个示例显示了相同的ReadNotSharedDirty请求,但RetToSrc = 1:

        

        在此图中,事务流程如下:

  1. RN-F_NID1向HN-F发出具有TxnID = A的ReadNotSharedDirty请求。
  2. 请求在HN-F处导致缓存未命中。
  3. HN-F向RN-F_NID2发出SnpNotSharedDirtyFwd监听。监听具有:
    • TxnID = B
    • FwdNID = 1
    • FwdTxnID = A
    • RetToSrc = 1
  4. RN-F_NID2使用CompData消息将缓存行转发到RN-F_NID1,其中包含以下字段:
    • TxnID设置为监听中的FwdTxnID值。
    • DBID设置为监听中的TxnID值。
    • RESP显示返回的缓存行可以在SC状态下缓存。
  5. 由于RetToSrc = 1,RN-F_NID2将缓存行发送到HN-F。缓存行以SnpRespDataFwded消息发送,其中FwdState = SC(共享干净)和RESP = SC_PD(共享干净_传递脏)。RESP中的此值告诉HN-F,缓存行在RN-F2处于SC状态,且RN-F2将该缓存行的回写责任传递给HN-F。
  6. 收到监听数据后,RN-F_NID1向HN-F发送带有TxnID = B的CompAck响应。

9. 原子操作

        为了支持Armv8.1架构中添加的原子指令,CHI-B提供了原子事务。互连使用原子事务将原子操作及其操作数从一个设备传输到另一个设备。使用原子操作而不是独占访问可以减少其他代理无法访问数据的时间。原子事务可以执行多个原子操作,并且可以在处理器内部或外部执行。

        原子操作是在没有另一个请求者干扰的情况下执行的读-修改-写序列。与AXI中的独占访问一样,原子事务允许请求者修改内存的特定区域的数据,同时确保其他请求者的写入不会破坏数据。

        在AXI3和4以及CHI-A中,请求者获取数据,执行操作,然后将结果写回以完成原子访问。CHI-B包含将原子操作传输到互连的选项,这允许操作更靠近数据所在位置执行。这提高了效率,减少了数据对其他请求者不可访问的时间。

        为了执行原子操作,目标需要一个算术逻辑单元(ALU)。也就是说,要使用原子操作,HN、SN或两者都需要一个ALU。来自CHI-B的原子事务支持是可选的,因此HN和SN并不总是需要具有ALU。请求者有一个配置引脚BROADCASTATOMIC,可以用于在下游系统不支持原子事务时阻止请求者生成原子事务。

        完整的原子事务结构是:

• 请求者向互连发出原子事务

• HN或SN具有ALU,因此它执行原子操作

• 根据操作,互连可能将地址的原始数据返回给请求者

10. RAS特性

        CHI-B添加了可靠性、可用性和可维护性(RAS)特性,以支持Armv8 RAS规范。RAS特性有助于错误检测系统调试,并在以下列表中进行描述:

• 数据损坏和数据检查表示数据已损坏

• 追踪标记功能用于性能分析和调试

10.1 数据损坏和数据检查

        典型的系统只能检测到多位错误,而无法纠正。这就是为什么多位错误通常被称为不可纠正的错误。相比之下,许多系统可以纠正单位错误。

        Arm RAS规范允许在不立即引发异常的情况下,将不可纠正的错误从生产者传播到消费者。为了允许传递损坏的数据,CHI-B包含数据损坏数据检查的RAS特性。这两个特性表明数据在系统的某个点已经损坏。CHI-B允许数据包中Poison、Datacheck和RespErr字段之间的互操作性。

        将数据标记为已损坏,并不立即表示发生了错误,这使得数据可以在系统中传播,直到数据被消耗。推迟错误指示意味着系统不必在每次检测到不可纠正的错误时引发异常。相反,可以将Poison字段分配给与相应缓存行一起的缓存。这允许系统访问和使用未损坏的数据。

        数据损坏以64位为单位,这意味着数据包中的Poison字段为每64位数据设置一个位,以表示它已损坏。例如,一个256位数据字段将具有一个4位宽的Poison字段。数据损坏必须对数据的有效部分进行准确处理。如果一个64位的数据Flit无效,那么该Flit的Poison将返回一个不关心值。

        在发生以下情况之一时,损坏的数据被认为已消耗:

• 数据用于计算

• 数据传播到不支持数据损坏的组件。因为这个组件不能使用Poison字段,所以它将停止跟踪被损坏的数据。为了跟踪该数据,系统必须得到一个异常。

        数据检查特性为数据字段提供奇偶校验保护。实现可以在互连的各个点测试DataCheck字段以查找损坏的数据。DataCheck以8位粒度操作,因此DataCheck字段中的每个位对应于数据字段中的一个字节。

10.2 追踪标记

        CHI-B包含TraceTag字段以帮助调试和性能分析。TraceTag的宽度只有1位,并且该字段被添加到每个通道。如果Flit中的TraceTag字段被设置,它表示向系统指示该Flit被标记为追踪目的。事务中的所有后续Flit也必须设置TraceTag。这包括从原始请求生成的所有新事务。

       例如,如果从RN-F到HN-F的请求中设置了TraceTag,那么从HN-F到SN-F的读请求也必须设置TraceTag字段。请求节点可以在初始请求中设置TraceTag,或者可以在互连的中间点设置TraceTag。例如,可以对互连的观察点进行编程,以在HN-F处为地址A的请求设置TraceTag。这个编程为HN-F处发出的任何针对地址A的Flit设置TraceTag,但从RN到HN-F的初始请求可能没有设置TraceTag。

        例如,初始TraceTag在互连中设置,然后为后续Flit设置。互连被编程以跟踪MakeUnique请求。事务流程如下:

1. 请求节点0向主节点发出地址A的MakeUnique请求,如下图所示:

2. 互连在由MakeUnique请求生成的监听和监听响应中设置TraceTag。

3. 请求节点2向主节点3发送地址A的ReadShared请求。从ReadShared生成的监听没有设置TraceTag。这一步如下图所示:

4. HN-F向请求节点0发送完成信号。完成信号已设置TraceTag。

        在此示例中,MakeUnique和ReadShared都针对地址A,但是只有在主节点3看到MakeUnique请求后才设置了TraceTag字段。为ReadShared请求生成的所有Flit都未被标记为追踪。

11. 协议迭代和扩展

        本节介绍了从CHI A版到C版的变化,并提供了一些新增功能的示例。

11.1 从CHI-A到CHI-B的变化

        以下表格描述了在CHI-B中所做的添加

CHI-B新增描述
MESI协议支持CHI-B增加了对MESI一致性协议的支持。这支持不使用Owned或Shared Dirty缓存状态的RN-F以及简化的Snoop过滤器。此更改添加了新的操作码ReadNotSharedDirty和SnpNotSharedDirty,它们保证数据不会以SharedDirty状态返回。SNP Flit还添加了字段DoNotGoToSD,以确保被监听的RN-F不会使缓存行处于SharedDirty状态。
SharedClean状态返回CHI-B增加了以Shared Clean状态返回缓存行的功能。HN-F可以通过在非转发类型的Snoops中使用RetToSrc字段来请求Shared Clean状态的缓存行副本。如果多个RN-Fs持有缓存行,HN-F仅为一个被监听的RN-F设置RetToSrc字段。这鼓励系统缓存中存在更多共享数据,而不仅仅是在CPU缓存中。这有助于减小监听RN-F以获取缓存行副本时存在的延迟。
WriteDataCancel操作码允许取消写请求此操作码在Data Flit上发布,仅适用于三种事务:WriteUniquePtl、WriteUniquePtlStash和WriteNoSnpPtl。为避免死锁情况,CHI-A允许系统中的一个RN使用Streaming Ordered WriteUniques Optimization(WUO)。使用WriteDataCancel操作码,可以在多个RN使用WUO时打破死锁情况。当使用WriteDataCancel时:• 为完成事务,仍必须发送所有响应和Data Flit。• 必须发送具有清零的Data和BE字段的WriteDataCancel消息
CleanSharedPersist为了将缓存行清理到持久性点,Armv8.2中添加了DC CVAP指令。有关持久性点的更多信息,请参阅Armv8-A架构配置文件的Arm架构参考手册Armv8。为支持Persistent Memory Transactions,添加了CleanSharedPersist操作码。执行DC CVAP指令会生成一个CleanSharedPersist事务。对持久性内存的支持是可选的,由配置输入引脚BROADCASTPERSIST指示:• 如果BROADCASTPERSIST = 1,可以向下游发布CleanSharedPersist事务。• 如果BROADCASTPERSIST = 0,请求方必须将CleanSharedPersist事务转换为CleanShared事务
CMO传播到SN可以将Cache Maintenance Operations从HN传播到SN。这允许SN支持HN下游的缓存。可以通过支持可选的BROADCASTCACHEMAINTENANCE、BROADCASTINNER和BROADCASTOUTER信号来控制CMO传播。当所有这些信号都存在且未触发时,CleanShared,CleanInvalid和MakeInvalid事务不会向下游发出。
DVM增强虚拟机标识符字段从8位扩展到16位。为支持此增强功能,SNP Flit中添加了VMIDExt字段以传输额外的8位(VMID[15:8])。此字段在DVM Snoops的第一部分中填充,第二部分中设置为0。VMID[15:8]在DVM请求的第二部分中传输,填充数据字段的位63:56。

        以下功能在CHI-B中已弃用

• 屏障事务和内部及外部共享域。由DMB或DSB指令生成的所有屏障事务必须在内核内终止。CHI-B互连不支持屏障,因此RN不应向外部发出它们。

• 内部和外部共享域。请求仅标记为可Snoop或不可Snoop。由于仅支持两种类型,Request Flit的SnpAttr字段从2位减少到1位。

11.2 从CHI-B到CHI-C的变化

以下表格描述了在CHI-C中添加的内容

CHI-C新增描述
CompAck响应更早发送CHI-C中的RN在接收到第一个数据Flit后可以发出CompAck消息。以前,RN需要等待所有读数据Flit到达后才能发出CompAck响应。
数据Flit操作码字段宽度增加数据Flit的操作码字段大小从3位增加到4位。这使得数据Flit宽度比CHI-B多1位。更宽的操作码字段需要支持新的数据消息DataSepResp。由于数据Flit增加了1位,CHI-C设备与CHI-B设备不直接兼容
合并写数据和CompAckCHI-C添加了一条新消息NCBWrDataCompAck,允许将CompAck响应与WriteUnique事务的写数据一起发送。
将读的响应和数据分开读事务可以接收完成和读数据的独立响应。为支持此功能,添加了两个新消息:• 在RSP通道上发送的RespSepData消息。此消息表示读已达到序列化点。HN将此消息发送给RN。此消息缩短了HN处的读请求寿命,因为RN可以在无序读后立即发送CompAck响应。从RN到HN的有序读有几个限制:◦ RN必须在发送CompAck给HN的有序读之前至少等待一个DAT Flit。◦ HN不得发送ReadReceipt响应,因为RespSepData消息充当ReadReceipt。• 在数据通道上发送的DataSepResp消息。这是仅发送读数据的数据消息。此消息可以由HN或SN发送,具体取决于是否使用DMT。

11.3 读事务示例

        读序列使用ReadNoSnpSep请求,该请求旨在与数据内存传输(DMT)一起使用,并从HN发送到SN。当SN看到此请求时,它知道要使用DataSepResp消息将读数据返回给RN独立响应和数据读序列可用于大多数读类型。此新序列的例外情况是

• 原子事务

• 排他访问

• 需要排序且无完成确认的ReadNoSnp或任何ReadOnce变体

        以下两个示例演示了使用独立响应和数据消息的读序列。第一个示例显示了SN-F单独发送数据。第二个示例显示了HN-F执行相同操作。在这两种情况下,系统由以下部分组成:

• 一个RN-F,RN-F_NID1

• 一个HN-F,HN-F_NID2

• 一个SN-F,SN-F_NID3

        以下图表显示了当响应来自HN,数据来自SN时的完整事务流程:

在此图表中,事务流程如下:

  1. RN-F向HN-F发出具有TxnID = A的ReadNotShareDirty请求。
  2. HN-F向SN-F发出ReadNoSnpSep请求,表明它不应向RN-F发送CompData响应。这意味着SN-F需要使用DataSepResp消息返回读取的数据,并将Order字段设置为1。这类似于优化的DMT序列。
  3. HN-F对请求进行序列化。
  4. HN-F向RN-F发出RespSepData消息。TxnID与原始请求的TxnID匹配,DBID字段与ReadNoSnpSep的TxnID匹配。
  5. SN-F确认请求并向HN-F发送ReadReceipt消息作为响应。
  6. RN-F接收到RespSepData。
  7. RN-F在未等待读数据的情况下向HN-F发出CompAck消息。
  8. 当数据可用时,SN-F使用DataSepResp消息将读数据发送给RN-F。 DataSepResp消息的TxnID,HomeNID和DBID字段与DMT序列相同。

        在之前的CHI版本中,RN-F必须等到接收到ReadNotSharedDirty请求的数据后才能发送CompAck。通过使用单独的响应和数据序列,显著减少了HN-F处事务的生命周期。

        在这第二个示例中,读数据通过DataSepResp消息由HN-F返回。以下图表显示了响应和数据都来自HN时的完整事务流程:

        在此图表中,事务流程如下:

  1. RN-F向HN-F发出ReadClean请求。
  2. HN-F用RespSepData消息回应RN-F。
  3. 与前一个示例不同,HN-F向SN-F发送普通ReadNoSnp。
  4. RN-F接收到RespSepData响应。
  5. RN-F向HN-F发送CompAck消息。
  6. SN-F使用CompData消息将数据发送给HN-F。
  7. HN-F使用DataSepResp消息将数据发送给RN-F。字段值为:

• TxnID与原始请求匹配。

• HomeNID为2,是HN-F的节点ID。

• DBID字段为B。

        与第一个示例一样,在接收到CompAck消息后,HN-F能够停止跟踪ReadClean请求。使用单独的响应和数据序列,HN-F在RN-F接收到数据之前收到了CompAck消息。

11.4 组合写数据和CompAck示例

        CHI-C提供了一种合并了CompAck响应和写数据的消息,称为NCBWrDataCompAck,其中NCBW代表非拷贝写回。这个新消息可以用于:

• 任何WriteUnique变体

• 流式有序WriteUnique

由于NCBWrDataCompAck传输写数据,因此必须在数据通道上发送。在发送数据之前,RN必须等待:

• 一个DBIDResp消息

• 一个Comp响应

        Comp和DBIDResp消息可以作为两个单独的响应发送,也可以作为组合的CompDBIDResp发送。我们来看两个关于NCBWrDataCompAck如何工作的示例。第一个示例使用组合的CompDBIDResp消息,第二个示例使用单独的消息。示例系统有一个RN-F和一个HN-F。这个例子使用组合的CompDBIDResp:

• RN-F向HN-F发送一个WriteUniqueFull请求,值为:

◦ TxnID = A

◦ ExpCompAck = 1

• HN-F发送CompDBIDResp,其中:

◦ TxnID与原始请求相同。

◦ DBID = B

• RN-F发送了结合CompAck与写数据的NCBWCompAck消息。

        以下图表显示了组合CompDBIDResp事务流程:

        在第二个示例中,系统保持不变,但HN-F发送单独的Comp和DBIDResp消息。

• RN-F向HN-F发送WriteUniqueFull请求,值为:

◦ TxnID = A

◦ ExpCompAck = 1

• HN-F执行两个操作:

◦ 发送与WriteUniqueFull的TxnID匹配的Comp消息

◦ 发送DBIDResp响应,表示它可以接收写数据。TxnID与Write请求的TxnID匹配,DBID = B

• RN-F接收两个消息。

• RN-F发送具有TxnID = B的NCBWrDataCompAck消息。

        以下图表显示了单独的Comp和DBIDResp事务流程:

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值