原始文檔:https://developer.arm.com/documentation/102407/0100/?lang=en
CHI 總線拓撲結構
CHI總線拓撲是實現自定義的,可以是RING/MESH/CROSSBAR的類型;
- RING 一般適用于中等規模芯片
- MESH 一般適用于大規模芯片
- CROSSBAR 一般適用于小規模芯片
上面總線拓撲的選擇,一般會參考訪問延時和RN/SN數量
CHI cacheline狀態
大的分類:
- Valid/Invalid來描述cacheline的狀態是否有效;
- Valid的cacheline,必須是Unique或者Shared的狀態;
– unique就是只有這個cache中存在,其他人(這里指RN)的cache里面都沒有這個地址/數據,只有unique的狀態才能被寫;
– shared表示RN自己手里有這個cacheline,但是其他人(RN)手里有沒有這個cacheline,不知道(可能有,也可能沒有); - Valid的cacheline,必須是clean或者dirty的狀態;
– clean表示這個cacheline不負責更新數據到主存,由于其他人可能刷數據到主存,所以clean的cacheline數據可能和主存不同;
– dirty指的是cahceline相對于主存已經被修改;當想把dirty的cacheline清掉時,要么把數據刷進主存,要么把dirty的責任轉給其他人(RN或者HN); - cacheline可以有partial或者empty的狀態:
– empty的cacheline,里面沒有有效數據,但是RN有對應操作的權限/特性(比如UCE的cacheline,RN是可以直接寫這個cacheline,invalid的話,還要snoop別人);
– partial狀態表示有一些數據是有效的(也可能全部有效或者全部無效);有可能因為先更新狀態但是數據還沒來,或者是數據先變了,但是狀態還沒變這種狀態cacheline被snoop時,CHI協議有額外的限制;
詳細的cacheline狀態:
Invalid(I)
cacheline是無效的(也就是這個cache沒有緩存這個地址/數據)
Unique Dirty(UD)
cacheline只存在于當前cache,認為相對于主存發生了修改;RN可以直接修改cacheline的數據(因為是Unique),如果收到snoop請求,必須把cacheline的數據給出去;
Unique Dirty Partial(UDP)
和UD的區別,一個是partial的狀態,另一個是被snoop的時候,不能直接把cacheline數據發給RN;
Shared Dirty(SD)
相對于主存有修改,并且有更新主存的責任;SD的cacheline也可能存在于其它人手里,但是其他人都是SC的狀態;Unique cacheline才能被寫,SD狀態怎么來的?有可能是snoop了別人的cacheline,或者dirty的責任傳遞到了這里;
Unique Clean(UC)
可以不用知會別人,直接修改cacheline數據;
Unique Clean Empty(UCE)
可以不用知會別人,直接修改cacheline數據;但是如果收到snoop的時候,不能給數據到home或者其他RN;
Shared Clean(SC)
可能存在于一個或多個cache里,也可能相對于主存有修改,但是這個cacheline evict的時候不負責刷主存;
CHI節點類型
有三大類節點:RN,HN,SN,另外還有一個MN;
-
RN節點細分:
– RNF,全一致性節點,有一致性cache,并且響應snoop請求;
– RNI,IO一致性節點,沒有一致性cache,不接受snoop;
– RND,支持DVM的節點,相比RNI多了一個能接受DVM事務; -
HN節點細分:
– HNF,全一致性節點,排序一致性內存的訪問以及給RNF發送snoop請求;
– HNI,非一致性HN,排序對于IO子系統的請求;
– MN,處理RN發出的DVM事務,DVM事務有時也由HND來實現; -
SN節點細分:
– SNF連接到支持一致性內存空間的內存設備;
– SNI連接IO外設或者非一致性內存;
CHI的SAM
CHI總線中每一個組件都有一個Node ID,CHI使用SAM負責物理地址到Node ID的轉換;
每個RN和HN都要有SAM;
對于RN SAM的要求:
- 必須完全描述整個系統的地址空間;
- 沒有組件對應的地址空間,要映射到一個能返回錯誤響應的節點;
- 所有RN的SAM必須是一致的,某個特定的地址只能去向特定的HN節點;
CHI通道
SNP通道的約束:
- 只有HNF和MN從SNP通道發起事務;
- RNF SNP通道只接收SNP事務;
- MN SNP通道只接收DVM事務;
CHI FLIT
FLIT就是數據包,下面是一個REQ Flit的示例:
每個通道都有一個FLITV信號,為高時下拍FLIT有效;當發送方有接收方credit的時候才可以發送;LCRDV信號傳輸credit;
CHI在FLIT中定義了很多ID域段:
- SrcID:用來路由FLIT,表示發送方的ID,每一個FLIT都要有SrcID;
- TgtID:表示接收這個消息的節點ID,除了snoop的FLIT都需要TgtID(snoop發給誰是實現自定義的,snoop可以廣播,也可以由SF來管理到底發給誰);
- TxnID:每個FLIT都需要,RN outstanding出去的事務必須有著唯一的TxnID,其位寬決定了RN能outstanding多少事務;
- Opcode:REQ FLIT需要,表示傳輸類型,并且決定了事務結構(比如區分讀寫事務);
- DBID:只存在于RSP或者數據FLIT,目標節點通過這個來分配寫數據buffer,并且可以要求一個完成響應來釋放buffer;
– 對于寫,RN收到收方響應帶的DBID之后才能發寫數據;
– 一些需要完成響應(表示RN已經收到了讀數據)的讀事務,也使用讀數FLIT據攜帶的DBID;
寫事務傳輸流示例
RN NodeID是1, SN NodeID是2:
- RN給SN發了個TxnID為3的寫請求;
- SN為這個事務分配一個可用的數據buffer(BDID 0),關聯到TxnID和SrcID;
- SN回DBIDResp給RN,TxnID為3,DBID為0;
- RN使用接收到的DBID 0和TxnID 3發給SN寫數據;
- 當傳輸完成的時候,SN的SBID 0對應的buffer空間可以釋放;
ReadNoSnp事務流示例
下面是ReadNoSnp事務;RN0發送ReadNoSnp請求,SN5提供讀數據:
-
RN發送ReadNoSnp到ICN,TgtID是HN3:
-
HN發ReadNoSnp到SN5來取回數據:
-
SN5使用CompData響應把數據回給HN3:
-
HN3把CompData給RN0:
WriteNoSnp事務流示例
下面是WriteNoSnp事務,RN0發給SN5:
-
RN0發給HN3 WriteNoSnp事務:
-
HN3返回CompDBIDResp事務給RN0,這表示HN3可以接收寫數據并且其它RN均可觀測到這個寫事務;
-
下面兩步是獨立的,可亂序:
a. HN3把WriteNoSnp發到SN5,接收CompDBIDResp響應:
b. RN0給HN3發送寫數據
-
HN3接收到SN5的CompDBIDResp和RN0的寫數據以后,HN3給SN5發送寫數據:
CHI的完成響應
CHI使用完成響應來維護下面事務的順序:
- RNF發出的事務
- RNF事務導致的Snoop
完成響應確保snoop事務和他前面的RNF的一致性事務,只有一致性事務完成之后,snoop事務才能被接收;
HNF是維護cache一致性和保序的中心點,比如:一個RNF正在outstanding訪問一個特定的cacheline,如果其它RN的請求導致需要snoop這個cacheline,HNF會暫停后面的這個事務;當第一個RNF的一次性操作完了之后,它會給HNF發送完成響應;這樣HNF就可以讓后面的snoop繼續往下走;
不是所有事務都需要完成響應,請求FLIT中包含ExpCompAck來標識是否需要完成響應;
下面是發送需要完成響應的讀事務:
snoop事務的CompAck
下面RN2要發一個地址A的ReadShared事務,這個時候HN3還沒有完成RN0的MakeUnique事務,所以ReadShared事務的snoop操作都被阻塞住;
HN3完成第一個事務的snoop操作之后,給RN0發送Comp_UC消息;RN0給HN3發送CompAck消息;
此時HN3可以執行RN2的事務所產生的snoop操作;
端點順序和請求順序
-
Endpoint Order:
- 定義: 維持從單個RN到單一SN的事務順序。
- 例子: 多個設備訪問一個可編程的寄存器區間,是Endpoint Order。
-
Request Order:
- 定義: 維持從單個RN到相同地址的事務順序。
- 例子: 一個SN對于有交疊的non_cacheable空間(Normal NC, Device-GRE 和Device-nGRE)的多筆操作需要保序;Request Order需要保序的地址空間粒度,是實現自己定義的;
如果設置了Endpoint Order,也就意味著Request Order;
只有一部分事務可以使用Request Order和Endpoint Order:
- ReadNoSnp和所有的ReadOnce事務
– RN發起ReadNoSnp或者ReadOnce類型事務需要保序;
– SN接收上述REQ,并回ReadReceipt消息,ReadReceipt表示可以發下一個需要保序的事務;
– 發送ReadReceipt之后,SN需要保證執行保序(按照接收的事務順序); - WriteNoSnp和WriteUnique類型事務:
– RN發起WriteNoSnp或者WriteUnique類型的事務要求保序;
– SN響應DBIDResp表示他可以接收這個消息,他的databuffer可以接收寫數據,并且RN可以發送下一個保序的REQ;
– 發完DBIDResp,SN需要保證執行保序;
保序舉例如下:
- RN給SN發起讀請求1,ReqOrder為1;
- RN給SN發讀請求2,ReqOrder為1,但是發不出去,因為前面這個讀還沒完成;
- SN回ReadReceipt給RN,表明第一個讀已經接收了;
- 下面兩個可以亂序:
a. RN發讀請求2給SN;
b. SN回給RN讀請求1的數據;
請求retry
有時候目標節點沒有資源來接收請求,為了不阻塞ICN,CHI提供了retry機制,SN需要依照請求來決定和記錄其對應的Pcrd;
可以使用不同類型的Pcrd來記錄不同的資源,比如讀寫使用分離的databuffer,那么每個buffer都可以使用不同的credit來標識;不同的Pcrd值是實現自定義的;
詳細流程不介紹了,看協議的2.3.8章節;
DVM事務
CHI使用DVM事務來維護虛擬內存;
DVM操作有如下事務:
- TLB清除;
- 指令cache清除
- 分支預測清除
- DVM同步
CHI中,所有的DVM事務分兩部分給MN,下面是順序要求:
- 第一部分是給MN發DVMOp請求,請求FLIT使用地址域段來編碼操作選項;
- 第二部分是當RN接收到MN的DBIDResp之后,通過data FLIT發送DVM消息;這一步攜帶了DVM事務目標地址;
當MN收齊了兩步DVM事務,MN給相關一致性domain的RN發起SVM snoop請求,也是分兩步,兩步必須使用相同的TxnID和opcode SnpDVMOp:
- 第一部分使用地址域段編碼操作屬性和目標地址高位;
- 第二部分使用地址域段發送剩余的地址;
上面兩部分是通過Address的bit[3]來標識;0表示第一步,1表示第二步;這兩步可以亂序;
DVM操作類型
CHI定義了兩類DVM事務:DVM Non-Sync和DVM Sync;這決定了RN是否先等當前操作完成再響應DVM snoop;
同步DVM只做同步動作;
非同步DVM非同步DVM就是 TLB/指令cache/分支預測 無效的操作;非同步DVM事務可以outstanding;
下面一個outstanding的例子:
- RNF/RND接收一個DVM Non-Sync的snoop操作;
- RNF/RND給MN發snoop響應,這只表明他接收了DVM事務,但不表示DVM事務的執行;
- MN給最初發DVM事務的RNF/RNI完成響應,表示別人已經收到DVM事務;
為了確保所有outstanding的DVM已經執行,看下面的例子:
- RNF發起同步DVM事務給MN,需要DVM Sync同步的outstanding的DVM事務,需要先回完成響應,才能發起DVM Sync;
- MN給所有的RNF和RND發起 DVM Sync的snoop;
- 每個RN需要確保前面收到的outstanding的DVM事務都已經執行;
- 所有RN給MN回snoop響應,表示所有的DVM操作已經執行完成;
- MN在給發DVM Sync的RN發起完成響應;
ARM核的DSB指令會產生DVM Sync操作,但是實現如果確認沒有需要同步的DVM操作時,可以不用發DVM Sync;
DVM操作流
下面是一個TLB無效的DVM事務 + DVM Sync;
- RN0給Mn發TLB無效的DVM事務;
- MN響應DBIDResp,表示他可以接收DVM事務的第二步;
- RN0給MN發起寫數據消息,作為DVM事務的第二步;
- MN給RN1發起兩步DVM事務;
- RN1通過給MN發送snoop響應表示已經接收DVM請求;
- MN接收snoop響應;
- MN給RN0發完成響應;
- RN0給MN發起DVM Sync;
- MN給RN0回DBIDResp;
- RN0給MN發寫數據消息, 作為DVM事務的第二步;
- MN給RN1發DVM Sync snoop;
- RN1執行完所有outstanding的DVM操作;
- RN1給MN發snoop響應,表示已經執行完所有操作;
- MN給RN0發完成響應,作為DVN Sync的響應;
Cache stashing
cache stash是把數據放在系統特定cache中的機制,通過把數據放在臨近將來要用的位置,減少訪問延時來提升系統的性能;
一般情況下,RNI和RND會發stash操作,stash請求只是一個建議,并不是強制的要求;一個設備收到stash類型的操作,也可以忽略掉;
CHI有兩種cache stash事務:帶數據的和不帶數據的;
stash傳輸流
基礎的傳輸示例:
- RN通過REQ通道發起stash請求;
- stash請求發給HNF;
- HNF可以有如下方式:
- 忽略stash事務,把它當成非stash的操作;
- 支持stash,給RNF發snoopRNF把cacheline預取至自己cache中;
- stash目標RNF收到一個Stashing Snoop;
RNF可以有如下方式:
- 回Snoop響應,就像收到使用datapull機制的cacheline讀一樣;
- 不使用datapull回snoop響應,然后發起那個cacheline的讀;
- 回snoop響應,不預取這個cacheline,忽略掉stash的提示;
stash snoop請求
所有的cache stash請求發給HNF節點,HNF處理cache stash請求,他會給RNF發stashing snoop;
CHI有四種類型的cache stash事務:
cache stash控制域段
stash事務REQ,snoop,response,data FLIT均有下面域段:
- stash目的節點NodeID
- RNF中的邏輯處理器cache,比如L2$
- 是否會使用datapull機制
stash事務REQ FLIT使用下面域段:
- StashNID
- StashNIDValid,標識是否有用StashNID
- StashLPID
- StashLPIDValid,標識StashLPID是否有使用;
snoop FLIT有如下域段:
- StashLPID和StashLPIDValid
- DoNotDataPull
寫數據的傳輸
RN發起WriteUniqueStash來寫一個新數據并且希望Target來stash這個數據;寫的cacheline可以是full或者partial;
下面是一個RNI發起stash操作的例子,目標節點是RNF:
- RNI發起WriteUniqueFullStash,為了簡化流程,例子不給RNF的DBIDResp
- HNF收到stash事務后發送SnpMakeInvalidStash給HNF
- RNF接收HNF的snoop
- RNF接收stash并且返回snoop resp
5. 如果使用datapull,RNF要么發起一個帶implicit讀請求的snoop響應,或者一個snoop響應和一個單獨的讀請求,這里是一個implicit snoop響應和讀請求,不是完整的datapull流程;
6. HNF發送從RNI收到的寫數據給RNF;
無寫數據的傳輸
- RNI發起StashOnceUnique請求到HNF;
- HNF接收stash請求;
- HNF給主存發ReadNoSnp來獲取cacheline,同時發起SnpStashUnique給RNF;
- 主存把cacheline數據給到HNF;
- RNF響應snoop,請求cacheline;
- HNF把cacheline數據給到RNF;
如果stash沒有對應的Target,那么HNF就是stash target;如果HNF要做stash,就發起ReadNoSnp到主存,拿到數據之后存到自己的cache里;
datapull機制
datapull機制是可以在snoop響應中帶一個讀請求,這樣可以少發一個讀請求;只在stash snoop中可以用;
RNF收到要求datapull的snoop,可以使用datapull或者單獨發一個讀請求;
I/O Deallocation
CHI提供了IO請求者釋放全一致性節點cacheline的提示操作;I/O Deallocation操作可以提示一個cacheline應當invalid掉,臟數據可以踢下去或者直接丟掉;因為是提示性操作,一致性節點也可以只回數據而不無效掉cacheline;注意提示性操作不能替代CMO;
CHI有兩種I/O deallocation事務:ReadOnceCleanInvalid和ReadOnceMakeInvalid;這倆對于防止cache被不在用的數據污染很有效(防止命中率下降),MakeInvalid和CleanInvalid的區別是,MakeInvalid是不踢入主存,直接把數據丟掉,所以使用時要小心一些;
I/O Deallocation示例
ReadOnceCleanInvalid的例子:
然后RNF無效掉自己的臟cacheline并刷到HNF中,HNF把數據給到RNI,并寫入主存;
DMT,DCT和PrefetchTgt
DMT和DCT可以讓數據直接在RN和SN之間傳輸,省的中間經過HN的轉發拖慢性能;但是傳輸完成的時候,HN仍然需要收到CompAck來確認傳輸已經完成;
PrefetchTgt事務可以減少內存訪問的延時,PrefetchTgt可以直接由RNF送到SNF,不需要返回數據,MC可以把這個作為一提示,提前把數據放到讀buffer中;這樣后面普通的讀下來的時候,數據可以很快回去;
DMT
對于讀事務的DMT傳輸,見下圖:
MC取回數據后直接把數據給到CPU;
使用DMT之后ICN的效率高了很多,絕大多數的讀操作都可以使用DMT,cache stash導致的DataPull也可以使用DMT;
不能使用DMT的請求:
- EX操作;
- ReadNoSnp并且ExpCompAck = 0并且Order != 0
- ReadOnce并且ExpCompAck = 0并且Order != 0
為了支持DMT,CHI包含了如下ID域段:
- REQ FLIT使用ReturnNID和ReturnTxnID
- DATA FLIT使用HomeNID
DMT傳輸流示例:
有order要求的DMT傳輸示例:
當HNF收到Read Receipt之后就可以把自己的資源釋放了;
Prefetch Target
PrefetchTgt可以提升DMT的效率,其由RN直接發給SNF,不需要響應,不需要TxnID,不計入outstanding,SNF也可以選擇忽略掉這個事務;
如果SNF決定預取數據,它會一直buffer住數據,直到發生了對這個地址的讀操作;一般情況下認為很快就有一個讀事務走常規路徑(RN->HN->SN)過來;
DATA FLIT的DataSource域段,可以用來指示RNPrefetchTgt事務是否有用:
— 0bR0110 PrefetchTgt 對于本次傳輸有用.
提前預取數據對于數據傳輸而言延時降低;
— 0bR0111 PrefetchTgt 本次傳輸沒有用
和普通的讀而言,本次數據預取沒有改善延時;
RN可以根據上面的反饋來調整是否發送PrefetchTgt;
流程比較好理解,這里就不詳細描述了;對于RN而言,就是在知道會miss的情況下先發PrefetchTgt再發讀事務;
DCT
為了減少snoop hit的延時,引入DCT;和DMT類似,DCT是用于snoop數據傳輸的;
對于信號量和生產者-消費者這種類型的工作負載(常見的并發控制和同步機制。這些用例從數據一致性技術中受益,因為它們通常涉及多個進程或線程共享和修改共同資源),DCT可以帶來性能提升。
Forward Snoop Requests
Forward Snoop 請求告訴被snoop的RNF把snoop數據直接給到原始的RN,除了原子事務和EX事務,均可使用DCT;
Forward Snoop需要下面域段:
- FwdNID
- FwdTxnID
- RetToSrc 為1要求snoopee把cacheline給到HN節點,防止后面訪問這個地址又要snoop;
DATA FLIT和RESP FLIT需要一個FwdState域段,這個域段告訴HNF DCT數據的cache狀態以供SF維護一致性; 同時cache狀態通常會在RESP域段中給到原始RNF;
和普通的讀一樣,原始RN通過CompData消息來接受snoop數據;
RetToSrc = 0的傳輸流圖:
RetToSrc = 1的傳輸流圖:
原子操作
使用原子操作,相比EX操作可以節省大量時間;原子事務可以一次執行多個原子性的操作不被打斷;
原子操作類型有四個:
- AtomicStore
- AtomicLoad
- AtomicSwap
- AtomicCompare
對于AtomicStore ,支持如下細分操作:
對于AtomicLoad,支持如下細分操作:
對于AtomicSwap,target把原始數據和事務攜帶數據相交換,再返回原始數據;
對于AtomicCompare,事務會攜帶兩個值,比較值和交換值,target拿比較值和原始數據進行比較,如果數據相等,target把swap值寫進去,如果不相等,target不會寫目標地址;返回數據為目標地址的原始數據;
下面是一個有數據返回的原子操作傳輸流,其他場景見協議5.4章節;
RAS特性
CHI支持下面RAS特性:
- 數據poison和datacheck來標識失效數據
- Trace Tag來幫助分析和調試
poison和datacheck
一般ECC算法都是糾一檢二,超過1bit錯誤哦叫做不可久錯誤(UR或者UCE,注意根據上下文和cache狀態相區別),把數據標記為有毒的,poison標識會和數據一起傳遞直到數據被消費,這允許即使數據錯了也可以讓系統使用;
poison的粒度可以是64或者128bit;
數據被消費的含義:
- 數據被用來做計算了;
- 數據被給到了不支持poison的地方;這種情況需要進入異常;
datacheck提供data域段的奇偶校驗,8bit粒度對應1bit的datacheck校驗位;
TraceTag
CHI每個通道都有1bit的TraceTag,TraceTag為1表示這個FLIT被標記來做trace,所有后面的FLIT也要打上trace標記,RN事務導致后面新產生的事務;比如導致HNF產生額外的命令;
TraceTag可以在初始RN節點置1,也可以在ICN的中間節點置1;比如中間的觀測節點可以把TraceTag置1;也可以中間的觀測節點被設置為所有路過去往地址A的事務都把TraceTag置1;
傳輸流示例:
- RN0發送地址A的MakeUnique請求到HN3:
- ICN把snoop和snoop的響應的TraceTag都置1;
- RN2發送ReadShared事務給HN3,ReadShared事務產生的snoop的TraceTag為0;
4. HNF給RN0發送完成響應,TraceTag為1;