在CHI协议中,每个请求可以生成一个或多个响应,不同响应表示Completer完成不同的操作之后,返回给requestor的通知。Requestor收到响应之后,根据响应类型来判断下一步需要做什么。
1. Observe响应
Observe响应确定一个transaction相对于来自于同一个requestor或其它requestors的 transactions之间的顺序。对于不同的属性,observe保证的地址范围不一致:
- 对于Cacheable属性:同一个cache line地址和NS属性的,不同cache line地址和NS属性的transaction,它们之间没有observe关系。
- 对于Non-cacheable或Device:相同的endpoint地址范围,这个endpoint地址范围通常是实现定义的,典型为:
- 如果用于peripheral device区域,那么是peripheral device大小;
- 如果用于memory区域,那么是cache line大小。
在CHI协议中有:CompData、DataSepResp、RespSepData、Comp、CompCMO和StashDone。针对不同请求类型(read、write、atomic、dataless等),需要用不同observe响应。本文以Write操作中Comp响应作为代表来举例。
2. Order响应
Order响应决定了requestor何时可以发送下一个需要保序的请求,它针对的是同一个requestor,且order保证的地址不要求。只要requestor收到order响应后,再发送其它的请求,那么completer一定会做好这两笔请求之间的保序。
在CHI协议中有:ReadReceipt、DBIDResp和DBIDRespOrd。本文以Write操作中的DBIDResp响应为代表来举例。
3. Observe响应和Order响应的区别
图1为WriteUnique的传输流程图。Completer在收到WriteUnique后,可以按任意顺序返回DBIDResp和Comp响应,这取决于Completer架构的设计。
图1 WriteUnique的传输流程图
根据Order响应的定义,这笔WriteUnique操作至少要到达Completer内部对当前requestor的保序点,Completer才可以返回DBIDResp响应,这里需要注意的是,按道理Completer确定WriteUnique到达某个对当前requestor的保序点就可以返回DBIDResp响应,不需要这笔WriteUnique到达Completer内部总的保序点。如下图2所示。
图2 允许返回DBIDResp的点
根据Observe响应的定义,这笔WriteUnique操作要等Completer操作把系统内其它requestor的数据都无效之后,Completer才会返回Comp响应。之所以需要都无效掉,举个例子,比如另一个Requestor1内部有同cache line的副本,那没有无效掉就返回Comp响应的话,Requestor1内部的读操作,读到的仍然是旧值,还无法observe到WriteUnique的新值。如下图3所示,只有执行了步骤2, 3,4之后,Completer才可以进行步骤5,不然就算Core0对0x80地址写了01,Core1还是没有observe到,因为Core1内部仍然在使用00数据。
图3 Comp响应返回时间点
根据Completer微架构的不同,同一笔request操作,返回Comp和DBIDResp响应的顺序是不固定的,谁先满足响应的条件,谁就可以先发送。另外,由于CHI总线通常采用Mesh或Ring结构,先发送的响应也不一定先到达Requestor。
4. DBIDResp响应举例
以Arm architecture定义的non-Reordering(nR)属性举个DBIDResp响应应用的具体例子。如果一个Core内部有两笔nR属性的store操作(storeA, storeB),它们访问的地址任意,但属于同一个peripheral device空间。那么Core需要如何发送通知CHI要做好这两笔store的保序呢?可以参考下图4和图5。
图4 WriteNoSnpA -> WriteNoSnpB -> WriteNoSnpC保序
图5 WriteNoSnpA和WriteNoSnpB不保序,WriteNoSnpB和WriteNoSnpC保序
Core在发送完第一笔StoreA的请求之后,需要等待下游返回DBIDResp响应后,再发送StoreB请求,这样下游就清楚StoreA和StoreB两者之间需要保序,否则,下游可能会乱序执行StoreA和StoreB,造成最终的结果与我们预期不一致。需要注意的是,如果Core收到StoreA的Comp响应,还没有收到DBIDResp响应,那么Core仍然不能发送StoreB,因为Comp响应是下游保证同address空间的保序。
Device属性的保序是按照Peripheral device空间来进行,所以在总线设计中,通常所有requestors的所有device请求都路由到同一个HN上去处理。而normal memory属性的地址空间通常可以按某些address位切割成很多份更小的空间,这些更小的空间有自己的HN,从而加速整个总线的并行处理能力。
5. 总结
综上所述,Observe响应和Order响应各有各的用法,两者之间功能有部分重叠,但又有部分完全含义不一致。Observe响应倾向于多个requestors在同范围内的保序,Order响应倾向于单个requestor在同范围内的保序。
大家对一致性协议原理和内存模型有疑问的话,可以读读这两篇文章。
一文读懂Memory consistency model (内存模型)
一文读懂Cache一致性原理
另外,感谢为本文提供思路的天才同事们提供的一些见解。