我们知道,CHI一定适用于多核的系统中的(好像是废话)。既然是多核系统,就不可避免的要面对一个顺序(order)问题。对于如何保序,CHI协议下了很大的功夫,分为以下几个部分。
-
Multi-copy atomicity
-
Completion Response and Ordering(用于RN保序)
-
Completion acknowledgement (用于RN request和其它RN snoop之间保序)
-
Transaction ordering (用于RN和HN之间保序)
我们一个一个来分析,首先是Multi-copy atomicity,协议中是这么写的:
对同一个位置的写操作必须串行化,这就要求必须有一个串行化点POS(一般位于ICN中)对所有的写操作排序;而且这个写操作要被所有的requester观测到,当然有那些不被允许的requester除外(可能由于虚拟化,或安全等原因);只有当写操作被所有requester观测到以后,才能对该地址的读请求返回数据。
Multi-copyatomicity属于consistency的范畴,这里的mulity-copy指的是多核拷贝,也就是说系统中的n个core都可以对内存系统的某个位置发起写操作。Multi-copyatomicity所要求的就是对于同一个地址的写操作有序。
接下来再看看Completion Response and Ordering,为了保证来自相同或不同agent的事务顺序,协议规定Comp、RespSepData、CompData或Persist响应须遵守如下规则:
-
对于访问Non-cacheable或Device memory的read transaction,RespSepData或CompData响应可以保证对同一端点地址范围的transaction会被任何agent随后的transaction观测到,端点的地址范围取决于具体实现;
-
对于访问Cacheable地址的Read transaction,CompData或DataSeqResp响应可以保证当前的transaction被后续任何agent发送的transactions观察到;
-
对于访问Cacheable地址的Read transaction,RespSepData响应可以保证没有前面的transactions将会发送snoop请求给这个Requester,仅当HN收到该笔read transaction的CompAck之后才允许后面的transactions需要发送snoop请;
-
对于Dataless transaction,Comp响应就可以保证同地址的当前transaction可以被任何agent的后续transactions观察到;
-
对于CleanSharePersist transaction,Comp响应可以保证先前写入同一内存位置的任何数据都是持久的;
-
对于CleanSharedPersistSep transactions,Persist应可以保证先前写入同一内存位置的任何数据都是持久的;
-
对于访问Non-cacheable或Device nRnE或Device nRE的Write或Atomic transactions,Comp或CompData响应可以保证同一端点地址范围的当前传输可以被任何agent的后续transactions观察到;
-
对于访问Cacheable或Device RE的Write或Atomic transactions,Comp或CompData响应可以保证同地址的当前传输可以被任何agent的后续transactions观察到。
第三个是Completion acknowledgement。对于Requester发送的transactions和其它Requester transactions引起的snoop transactions之间的相对顺序是通过Completion Acknowledgment响应来控制的的。
一笔read transaction完成和发送CompAck之间的顺序如下:
-
RN-F在收到Comp、RespSepData或CompData、或RespSepData和DataSepResp两者之后,才发送CompAck;
-
除了ReadOnce*,HN-F只有在收到CompAck之后,才会发送下一笔同地址的snoop transaction;对于CopyBack transactions,WriteData充当隐式CompAck,因此HN必须等到WriteData之后再发送同地址的snoop transaction;
上述顺序保证了RN-F接收transaction的完成和snoop到同一缓存行的顺序与从HN-F发送的顺序相同。这样可以确保以正确的顺序观察到同一缓存行的事务。
对于RN和HN之间的transaction,如果HN是completer,HN必须能够支持CompAck。SN不需要支持CompAck。
除了Comp响应用于保证一个Requester的多个transactions的顺序,CHI协议也定义了一些机制,用于RN和HN、HN-I和SN-I之间的保序。在一笔request中,RN与HN、HN-I与SN-I,这些对之间的Requester Order是通过Order字段来表示的,Order字段表示transaction需要以下某种形式的排序:
-
Request Order:保证从同一个agent发往同一个地址的多笔transactions的顺序;
-
Endpoint Order:保证从同一个agent发往同一个Endpoint地址范围的多笔transactions的顺序,包含了Request Order;
-
Ordered Write Observation:保证对于同一个agent的一串写操作,会被其它agents以相同的顺序观察到;
-
Request Accepted:保证Completer如果接收了该request,则会发送acknowledgement响应;
为了防止REQ通道被拥堵,CHI协议提供了一种request retry机制,当一个request到达completer端,要么被接受,要么发回一个RetryAck响应。Request retry不适用于PrefetchTgt,因为没有对PrefetchTgt来说没有相应的响应。
Requester需要记录发出去的request,如果收到相应的响应,就说明该笔transaction完成,如果收到RetryAck,则需要重发这笔request。
当Completer在没有资源和没有足够存储空间来存放当前的request时,会对Requests进行retry,如果更早的transactions完成并释放资源了,就可以发送PCrdGrant响应允许二次发送命令。当Completer对request进行retry,它需要记录该笔request的来源,也需要决定和记录Protocol Credit的类型,因为后续PCrdGrand的P-Credit type要和RetryAck中的一致。当Completer有资源后,它必须发送通过PCrdGrant响应发送P-Credit给Requester。
retry机制最多支持16种不同的信用类型。允许completer对不同的资源使用不同的信用类型。例如,completer可以对与read transaction关联的资源使用一种信用类型,而对write tansaction使用另一种信用类型。通过使用不同的信用类型,completer可以通过控制哪些重试请求可以再次发送来有效地管理其资源。
Requester可能收到比需要更多的P-Credits,CHI协议没有定义这种场景,但有两种典型的场景是:
-
在第一次发送到收到PCrdGrant之间就把transaction取消掉了;
-
一笔transaction要求随着Qos值的增加多次传输,但是只有一笔完成响应需要;
Requester通过PCrdRetrun返回P-Credit,告知Completer PCrdType分配的资源已经不需要了,任何不需要的P-Credit都需要及时释放掉,不能保留它们以备后续使用。
下面是transaction retry的一个例子:
-
Requester发送ReadOnce;
-
Completer接收到request,因为当前时刻不能处理这个request,所以发送RetryAck;
-
当completer有了足够资源来处理这笔request,通过PCrdGrant响应返回一个P-Credit;
-
Requester重新发送这笔request。