一文讀懂Cache一致性原理
1.為何需要cache一致性
訪(fǎng)問(wèn)memory數(shù)據(jù)的速度與core的運(yùn)行速度相比,要花費(fèi)更多的時(shí)鐘周期。為了減少這個(gè)差異計(jì)算機(jī)系統(tǒng)引進(jìn)了存儲(chǔ)器層次結(jié)構(gòu),如圖1所示。在層次結(jié)構(gòu)中,越往上,讀寫(xiě)速度越快,價(jià)格越貴,存儲(chǔ)容量也越小。
圖1 存儲(chǔ)器結(jié)構(gòu)層次
隨著摩爾定律的發(fā)展,人們?cè)噲D增加CPU的core數(shù)以提升系統(tǒng)整體性能,這類(lèi)系統(tǒng)稱(chēng)之為多core系統(tǒng)。一個(gè)包含多core的系統(tǒng)中,每個(gè)core可能都有自己的私有cache,并且有可能會(huì)對(duì)相同的memory地址進(jìn)行修改。如果多個(gè)core同時(shí)對(duì)同一memory地址進(jìn)行讀寫(xiě)操作,很可能導(dǎo)致cache內(nèi)容不一致,從而導(dǎo)致數(shù)據(jù)不一致,最終造成系統(tǒng)出錯(cuò)和崩潰。因此,在設(shè)計(jì)多core系統(tǒng)時(shí),必須考慮cache一致性(cache coherency)問(wèn)題來(lái)確保數(shù)據(jù)的正確性和系統(tǒng)的穩(wěn)定性。舉個(gè)例子,假設(shè)2個(gè)core的系統(tǒng),每個(gè)core私有的L1 cache的cacheline大小是64Bytes。兩個(gè)core都讀取0x80地址數(shù)據(jù),導(dǎo)致0x80開(kāi)始的64Bytes數(shù)據(jù)都分別加載到core0和core1的私有L1 cache中。
圖2 兩core系統(tǒng)讀取0x80地址的數(shù)據(jù)
core0對(duì)0x80執(zhí)行寫(xiě)操作,寫(xiě)入值為0x01。Core0的私有L1 cache更新對(duì)應(yīng)cacheline的值。然后,core1讀取0x80的數(shù)據(jù),core1發(fā)現(xiàn)命中自己私有L1 cache,然后返回0x00值,并不是core0寫(xiě)入的0x01值,這就造成了core0和core1的私有L1 cache數(shù)據(jù)不一致現(xiàn)象。
圖3 core0更新0x80地址的數(shù)據(jù)
按照正確的處理流程,可以使用以下兩種方法保證多core cache的一致性:
- Core0修改0x80地址數(shù)據(jù)的時(shí)候,除了更新core0的私有cache之外,還應(yīng)將修改的數(shù)據(jù)通知到core1的私有cache去更新0x80地址的數(shù)據(jù)。
- Core0修改0x80地址數(shù)據(jù)的時(shí)候,除了更新core0的私有cache之外,還應(yīng)通知core1的私有cache將0x80地址所在的cacheline置為無(wú)效。保證core1讀取數(shù)據(jù)時(shí)不會(huì)命中自己的cache。這樣core1就必須重新從core0或memory中去讀取0x80地址最新的數(shù)據(jù)。
Cache一致性可以通過(guò)軟件和硬件來(lái)解決,通常來(lái)說(shuō),軟件維護(hù)cache一致性維護(hù)成本太高,會(huì)導(dǎo)致性能下降?,F(xiàn)在的實(shí)現(xiàn)方案基本都是使用硬件來(lái)自動(dòng)維護(hù)多核cache的一致性,并且對(duì)軟件和程序員來(lái)說(shuō)是透明的。因此,本文只介紹硬件維護(hù)cache一致性。硬件維護(hù)cache一致性需要制定一致性協(xié)議,一致性協(xié)議是由系統(tǒng)內(nèi)的各個(gè)分布式硬件參與者組件共同實(shí)現(xiàn)和維護(hù)的一組規(guī)則。一致性協(xié)議有許多版本,Arm的ACE(AXI Coherency Extensions)和CHI(Coherent Hub Interface),AMD的Coherent HyperTransport(HT),Intel的QuickPath Interconnect(QPI)等等。
2.一致性協(xié)議的本質(zhì)
雖然一致性協(xié)議眾多,但本質(zhì)上講,所有一致性協(xié)議都通過(guò)將寫(xiě)入的數(shù)據(jù)傳播到所有一致性cache來(lái)使一個(gè)core的寫(xiě)入對(duì)其它c(diǎn)ore可見(jiàn)。具體來(lái)說(shuō)有兩點(diǎn)原則:
- Single-Writer, Multiple-Read(SWMR):在任意時(shí)刻,對(duì)于任意的memory地址A,只有一個(gè)core可以寫(xiě)它(也可以讀它),或者多個(gè)core讀它。因此,永遠(yuǎn)不會(huì)有這樣的情況:一個(gè)core可以寫(xiě)入memory地址A,而其它c(diǎn)ore可以同時(shí)讀取或?qū)懭朐搈emory地址A。如下圖4所示,可以把時(shí)間會(huì)切割為無(wú)限小的切片,在每個(gè)切片中,對(duì)于memory地址A,要么單個(gè)core具有讀寫(xiě)訪(fǎng)問(wèn)權(quán)限,要么若干core(可能為0)具有只讀訪(fǎng)問(wèn)權(quán)限。比如T1和T4時(shí)刻,允許多個(gè)core對(duì)同一個(gè)memory進(jìn)行讀取,但在T2和T3種,只能存在1個(gè)core擁有讀寫(xiě)的權(quán)限。
- Data-Value:在時(shí)間切片中,上一個(gè)時(shí)間切片結(jié)束的數(shù)據(jù)值與下一個(gè)時(shí)間切片開(kāi)始的數(shù)據(jù)值相同,即使同一個(gè)切片中,每個(gè)core讀取到的值必須相同。也就是memory地址的數(shù)據(jù)值需要被正確傳播。比如在T1時(shí)刻,如果core2和core5可以讀取到不同的值,那么就不符合一致性系統(tǒng)。同樣的,如果T3的core1沒(méi)有讀到T2的core3最后寫(xiě)的數(shù)據(jù)值,或者T4的core1/core2/core3沒(méi)有讀到T3的core1最后寫(xiě)的數(shù)據(jù)值,那么也不符合一致性系統(tǒng)。
圖4 不同core讀寫(xiě)的時(shí)間順序
對(duì)于SWMR還有另一種有意思的方式來(lái)解釋?zhuān)瑢?duì)于每個(gè)memory地址,存在固定數(shù)量的令牌,其數(shù)量至少與core數(shù)量一樣。如果一個(gè)core擁有所有的令牌,它就可以寫(xiě)入memory地址,而且core必須至少有1個(gè)令牌,才能對(duì)memory地址進(jìn)行讀取數(shù)據(jù)。因此,在任何給定的時(shí)刻,當(dāng)有core正在讀寫(xiě)memory地址的數(shù)據(jù)時(shí),其它c(diǎn)ore正在寫(xiě)入memory地址是不可能的。
一致性協(xié)議的兩點(diǎn)原則在設(shè)計(jì)一致性協(xié)議時(shí)至關(guān)重要。舉個(gè)比較常用的一致性無(wú)效協(xié)議(invalidate protocols)的設(shè)計(jì)方法:1.如果一個(gè)core想要讀取memory地址A,它會(huì)向其它c(diǎn)ore發(fā)送消息,以獲取memory地址A當(dāng)前的最新值,并確保沒(méi)有其它c(diǎn)ore緩存該memory地址A的cacheline擁有寫(xiě)權(quán)限的狀態(tài)。2.如果一個(gè)core想要寫(xiě)入memory地址A,它會(huì)向其它c(diǎn)ore發(fā)送消息以獲取memory地址A的當(dāng)前值,并確保沒(méi)有其它c(diǎn)ore緩存該memory地址A的cacheline擁有只讀或讀寫(xiě)權(quán)限的狀態(tài),也就是其它c(diǎn)ore都要無(wú)效掉自己緩存中memory地址A的cacheline。
3.一致性協(xié)議的類(lèi)別
設(shè)計(jì)一致性協(xié)議決定了在每個(gè)參與一致性的組件控制器上可能擁有哪些cache狀態(tài)、發(fā)送或響應(yīng)哪些一致性事務(wù)(transactions)操作、發(fā)生哪些事件(events)以及cache狀態(tài)轉(zhuǎn)換(transitions)等。設(shè)計(jì)一致性協(xié)議的方法有很多。
3.1 監(jiān)聽(tīng)和目錄
根據(jù)一個(gè)core的行為通知到其它c(diǎn)ore的方式可以分為監(jiān)聽(tīng)協(xié)議(Snooping protocol)和目錄協(xié)議(Directory protocol)。
3.1.1 監(jiān)聽(tīng)協(xié)議
監(jiān)聽(tīng)協(xié)議是第一類(lèi)廣泛使用的協(xié)議,最初主導(dǎo)了商業(yè)市場(chǎng),它們現(xiàn)在還有在各種小系統(tǒng)中使用。這種協(xié)議比較簡(jiǎn)單,當(dāng)cache miss發(fā)生時(shí),cache的控制器會(huì)發(fā)出仲裁請(qǐng)求給共享總線(xiàn)廣播它的請(qǐng)求。共享總線(xiàn)確保所有cache控制器以相同的順序觀察到所有請(qǐng)求。監(jiān)聽(tīng)協(xié)議依賴(lài)共享總線(xiàn)以一致的順序向所有cache控制器發(fā)送廣播消息,因此分布式cache控制器能夠正確的更新自己的有限狀態(tài)機(jī),這些有限狀態(tài)機(jī)共同代表了cache line的狀態(tài)。
要求以一致的總順序(total order)觀察廣播對(duì)于實(shí)現(xiàn)傳統(tǒng)監(jiān)聽(tīng)的共享總線(xiàn)具有重要意義。因?yàn)樵S多cache控制器可能同時(shí)嘗試發(fā)出一致性請(qǐng)求,共享總線(xiàn)必須將這些請(qǐng)求序列化成某種總順序(total order)。無(wú)論總線(xiàn)如何決定這個(gè)順序,這個(gè)機(jī)制被稱(chēng)為監(jiān)聽(tīng)協(xié)議的保序點(diǎn)(serialization point或ordering point)。在一般情況下,一個(gè)cache控制器發(fā)出一個(gè)一致性請(qǐng)求,總線(xiàn)在保序點(diǎn)將它排序并廣播給所有cache控制器,包括發(fā)出請(qǐng)求的cache控制器,因此發(fā)出請(qǐng)求的cache控制器可以通過(guò)收到的監(jiān)聽(tīng)請(qǐng)求流來(lái)判斷它的請(qǐng)求在什么時(shí)候被處理了,在總順序中排在哪個(gè)位置。
舉個(gè)例子,監(jiān)聽(tīng)協(xié)議總線(xiàn)使用仲裁邏輯來(lái)確保一次只在總線(xiàn)上廣播一個(gè)請(qǐng)求。仲裁邏輯充當(dāng)保序點(diǎn),它有效地決定了各個(gè)一致性請(qǐng)求在總線(xiàn)上出現(xiàn)的順序。有個(gè)微妙的點(diǎn)是,cache控制器的一致性請(qǐng)求是在仲裁邏輯順序就排好序的,但是cache控制器只能通過(guò)監(jiān)聽(tīng)來(lái)觀察到這個(gè)順序,進(jìn)而判斷自己請(qǐng)求的排序情況。因此,cache控制器的請(qǐng)求在保序點(diǎn)排好序后,可能會(huì)晚幾個(gè)周期才能被cache控制器觀察到請(qǐng)求順序。
監(jiān)聽(tīng)協(xié)議的latency比目錄協(xié)議低,而且實(shí)現(xiàn)也比較簡(jiǎn)單,但是不易擴(kuò)展。
圖5 監(jiān)聽(tīng)協(xié)議例子
3.1.2 目錄協(xié)議
目錄協(xié)議最初是為了解決監(jiān)聽(tīng)協(xié)議缺乏可擴(kuò)展性的問(wèn)題而開(kāi)發(fā)的。目錄協(xié)議會(huì)創(chuàng)建一個(gè)目錄來(lái)維護(hù)每一個(gè)cacheline的一致性狀態(tài)的全局視圖。該目錄跟蹤各cache保存了哪些cacheline以及處于什么狀態(tài)。Cache控制器發(fā)出的一致性請(qǐng)求將直接單播給目錄控制器(通常也稱(chēng)作home)。目錄控制器要么直接響應(yīng)請(qǐng)求,要么根據(jù)目錄信息將請(qǐng)求轉(zhuǎn)發(fā)給一個(gè)或多個(gè)其它c(diǎn)ache控制器,然后由后者響應(yīng)。目錄協(xié)議使用間接層來(lái)避免有序廣播網(wǎng)絡(luò)和讓每個(gè)cache控制器處理每個(gè)請(qǐng)求。一致性請(qǐng)求傳輸流程通常包括兩個(gè)步驟(單播請(qǐng)求,然后是單播響應(yīng))或三個(gè)步驟(1個(gè)單播請(qǐng)求,K個(gè)轉(zhuǎn)發(fā)請(qǐng)求和K個(gè)響應(yīng),其中K是共享者的數(shù)量)。有些協(xié)議甚至還有第四部,因?yàn)轫憫?yīng)間接通過(guò)目錄控制器,或者因?yàn)檎?qǐng)求者在一致性流程完成時(shí)通知目錄控制器。相比之下,監(jiān)聽(tīng)協(xié)議將一個(gè)cacheline的狀態(tài)分布在所有cache控制器上,由于這種分布式狀態(tài)沒(méi)有中央單元記錄信息,一致性請(qǐng)求必須被廣播到所有cache控制器上。因此監(jiān)聽(tīng)協(xié)議的一致性請(qǐng)求流程總需要兩個(gè)步驟(廣播請(qǐng)求,然后是單播響應(yīng))。
在大多數(shù)目錄協(xié)議中,一致性請(qǐng)求在目錄控制器處排序,多個(gè)cache控制器可以同時(shí)向目錄控制器發(fā)送一致性請(qǐng)求,目錄控制器會(huì)序列化這些請(qǐng)求并排好序。如果兩個(gè)請(qǐng)求同時(shí)到達(dá)目錄控制器,目錄控制器會(huì)選擇首先處理哪個(gè)請(qǐng)求,第二個(gè)處理的請(qǐng)求的命運(yùn)取決于目錄協(xié)議和請(qǐng)求的類(lèi)型。第二個(gè)處理的請(qǐng)求可能:(a)在第一個(gè)請(qǐng)求之后立即得到處理;(b)暫時(shí)保存在目錄中等待第一個(gè)請(qǐng)求完成;(c)直接發(fā)送否定響應(yīng)。在后一種情況下,目錄控制器向請(qǐng)求者發(fā)送否定確認(rèn)響應(yīng),請(qǐng)求者必須重新發(fā)出其一致性請(qǐng)求。
目錄協(xié)議在目錄控制器上排序,因?yàn)榇蠖鄶?shù)目錄協(xié)議不使用總順序的廣播,沒(méi)有序列化的全局概念。更確切說(shuō),一個(gè)一致性請(qǐng)求者相對(duì)于可能有副本的所有cache,必須單獨(dú)序列化。需要其它c(diǎn)ache顯示的消息通知請(qǐng)求者的請(qǐng)求已被相關(guān)cache處理和序列化。比如說(shuō),對(duì)于想獲取寫(xiě)權(quán)限的一致性請(qǐng)求,有共享副本的每個(gè)cache控制器一旦完成序列化了無(wú)效消息,都必須顯示地發(fā)送確認(rèn)消息。
目錄協(xié)議需要更少的總線(xiàn)帶寬,實(shí)現(xiàn)了更大的可伸縮性,但代價(jià)是總線(xiàn)某些一致性請(qǐng)求的latency。
圖6 目錄協(xié)議例子
3.2 無(wú)效和更新
根據(jù)一個(gè)core決定寫(xiě)cache line時(shí),一致性協(xié)議中其它c(diǎn)ore的cache line副本如何處理,可以分為:無(wú)效協(xié)議(Invalidate protocol)和更新協(xié)議(Update protocol)。這個(gè)分類(lèi)的選擇與協(xié)議是監(jiān)聽(tīng)還是目錄類(lèi)型無(wú)關(guān),它們可以?xún)蓛山徊?,組成4種類(lèi)型的一致性協(xié)議。
3.2.1 無(wú)效協(xié)議
當(dāng)一個(gè)core需要往某cacheline寫(xiě)入一個(gè)值時(shí),cache控制器會(huì)啟動(dòng)一個(gè)一致性請(qǐng)求來(lái)使所有其它c(diǎn)ache中對(duì)應(yīng)的cacheline副本無(wú)效。一旦所有副本都無(wú)效后,請(qǐng)求者就可以將數(shù)據(jù)寫(xiě)入該cacheline中,這樣就確保其它c(diǎn)ore不會(huì)讀取到舊值。如果另一個(gè)core希望在其副本無(wú)效后讀取該cacheline的值,則必須啟動(dòng)一個(gè)新的一致性請(qǐng)求來(lái)獲取該cacheline的數(shù)據(jù),并且它將從寫(xiě)該cacheline的core處獲取副本,從而保證了數(shù)據(jù)一致性。
圖7 無(wú)效協(xié)議例子 (1->2->3->4->5->6)
3.2.2 更新協(xié)議
當(dāng)一個(gè)core需要往某cacheline寫(xiě)入一個(gè)值時(shí),它會(huì)啟動(dòng)一個(gè)一致性請(qǐng)求來(lái)更新所有其它c(diǎn)ache中的副本,這樣所有cache用到的都是新值。
圖8 更新協(xié)議例子 (1->2->3->4->5->6)
這兩種協(xié)議的選擇需要權(quán)衡,更新協(xié)議減少了core讀取新值的latency,因?yàn)閏ore不需要初始化并等待重讀一致性請(qǐng)求的完成。更新協(xié)議通常要比無(wú)效協(xié)議消耗更大的帶寬,因?yàn)楦聟f(xié)議除了傳輸?shù)刂罚€要傳輸新值數(shù)據(jù)。此外,更新協(xié)議會(huì)使許多memory一致性模型的實(shí)現(xiàn)變得非常復(fù)雜。例如,當(dāng)多個(gè)cache必須對(duì)一個(gè)cacheline的多個(gè)副本進(jìn)行多個(gè)更新時(shí),保持寫(xiě)操作的原子性非常困難。由于更新協(xié)議的復(fù)雜性,它們很少被實(shí)現(xiàn)。
監(jiān)聽(tīng)和目錄與無(wú)效和更新,這些可以檢查混合搭配,組成四種類(lèi)型的一致性協(xié)議:監(jiān)聽(tīng)&&無(wú)效、監(jiān)聽(tīng)&&更新、目錄&&無(wú)效、目錄&&更新。Arm的ACE和CHI使用就是目錄&&無(wú)效組合。
4. 一致性協(xié)議的設(shè)計(jì)
4.1 狀態(tài)(states)選擇
4.1.1 狀態(tài)的特征
只有一個(gè)core的系統(tǒng)中,cache line的狀態(tài)要么有效要么無(wú)效。如果需要區(qū)分dirty狀態(tài),則cacheline可能有兩種有效狀態(tài)。Dirty的cache line具有比memory更新的數(shù)據(jù)。具有多個(gè)core的系統(tǒng)也可以只使用這兩三種狀態(tài),但通常需要區(qū)分不同類(lèi)型的有效狀態(tài)。cache line狀態(tài)有四個(gè)主要特征:validity、dirtiness、exclusivity和ownership。后兩個(gè)特征是具有多core的系統(tǒng)所特有的。
- Validity:一個(gè)有效的cache line具有該cache line的最新值。Cache line可以被讀,但只有在它也是exclusivity的情況下才可以被寫(xiě)。
- Dirtiness:如果一個(gè)cache line的值是最新的,且這個(gè)值與memory中的值不一致,那么這個(gè)cache line就是dirty的,緩存控制器負(fù)責(zé)最終用這個(gè)新值更新memory內(nèi)容。Clean通常被用作dirty的反義詞。
- Exclusivity:如果一個(gè)cache line在系統(tǒng)中是唯一的cache line副本,則該cache line是exclusivity的,也就是該cache line除了可能在memory中,沒(méi)有任何其它c(diǎn)ache擁有這個(gè)cache line的值。
- Ownership:如果cache控制器(或memory控制器)負(fù)責(zé)響應(yīng)cache line的一致性請(qǐng)求,那么它就是這個(gè)cache line的owner。在大多數(shù)協(xié)議中,一個(gè)給定cache line始終只有一個(gè)owner。如果沒(méi)有將cache line的ownership交接給另一個(gè)一致性控制器,就算是由于cache容量或沖突缺失,這個(gè)cache line可能也不會(huì)從cache中被踢出去以騰出空間給另一個(gè)cache line。在某些協(xié)議中,非owned的cache line可能會(huì)被悄悄無(wú)效掉,不發(fā)送任何消息通知其它組件。
4.1.2 MOESI狀態(tài)模型
許多一致性協(xié)議使用經(jīng)典的五態(tài)MOESI模型的子集。MOESI是cache中l(wèi)ine的狀態(tài),最基本的三種狀態(tài)時(shí)MSI,也可以使用O和E態(tài),但是它們不是最基本的。O和E態(tài)通常是協(xié)議中優(yōu)化某些場(chǎng)景使用的。這些狀態(tài)中的每一個(gè)都可以由上一小節(jié)描述的狀態(tài)特征組合而成。
- M(odified):cache line是valid、exclusive、owned、并且可能是dirty的。這條line可以被讀或?qū)?,且是cache中唯一的有效副本,擁有這條line的cache必須響應(yīng)其它c(diǎn)aches對(duì)這條line的請(qǐng)求,并且這條line在memory中的副本可能已經(jīng)過(guò)期了。
- S(hared):cache line是valid,但不是exclusive、dirty和owned的。這條line只能被讀,其它c(diǎn)aches也可能具有這條line的有效只讀副本。
- I(nvalid) :cache 里是invalid,cache要么不包含這條line,要么包含可能無(wú)法讀取或?qū)懭氲年惻f副本。
- O(wned) :cache line是valid,owned、且可能是dirty的,但不是exclusive的。這條line只能被讀,并且擁有這條line的cache必須響應(yīng)其它c(diǎn)aches對(duì)這條line的請(qǐng)求。其它c(diǎn)ache也可能有這條line的只讀副本,但它們不是owners。這條line在memory中的副本可能已經(jīng)過(guò)期了。
- E(xclusive):cache line是valid、owned、exclusive和clean的。這條line可以被讀或?qū)?,沒(méi)有其它c(diǎn)ache擁有這條line的有效副本,并且這條line和memory中的數(shù)據(jù)是一致的,memory中的副本是最新的。(需要注意的是,某些協(xié)議中,Exclusive不被視為owned的)
圖9用Venn圖展示了MOESI狀態(tài)。Venn圖可以展示哪些狀態(tài)共有哪些特征。除了I之外的所有狀態(tài)都有效。M、O和E是ownership狀態(tài)。M和E都是exclusivity,因?yàn)闆](méi)有其它c(diǎn)ache擁有該line的有效副本。M和O都是表示該cache line可能是dirty的。M、O、E和S組成了V(alid)態(tài)。
圖9 MOESI狀態(tài)的Venn圖
MOESI狀態(tài)模型雖然很常見(jiàn),但不是所有的狀態(tài)集合。例如,有些協(xié)議有F(orward)狀態(tài),它類(lèi)似與O狀態(tài),除了它是clean的,即memory中的副本是最新的。Intel Core i7-9xx處理器中的QuickPath Interconnect(QPI)就使用了F狀態(tài),QPI支持MESIF的5個(gè)狀態(tài)模型。
表1 MOESI的狀態(tài)特征
4.2 事務(wù)(transaction)選擇
一致性控制器組件的基本目標(biāo)都是相似的,所以大多數(shù)一致性協(xié)議都有類(lèi)似的transaction集合。例如,幾乎所有協(xié)議都有一個(gè)獲取Shared(只讀) cache line的transaction。表2列出了一組常見(jiàn)的transactions,并且對(duì)于每個(gè)transaction,描述發(fā)起transaction的請(qǐng)求者目標(biāo)。這些transactions都是由cache控制器發(fā)起的,這些cache控制器響應(yīng)來(lái)自其對(duì)應(yīng)core的讀寫(xiě)請(qǐng)求。表3列出了一個(gè)core可以像其cache控制器發(fā)出的讀寫(xiě)請(qǐng)求,以及這些core請(qǐng)求如何引導(dǎo)cache控制器發(fā)起一致性transactions。
表2 常見(jiàn)的transactions
盡管大多數(shù)協(xié)議使用類(lèi)似的transactions集合,但它們?cè)谝恢滦钥刂破魅绾谓换ヒ詧?zhí)行transaction方面存在相當(dāng)大的差異。正如我們之前提到,在監(jiān)視協(xié)議中,cache控制器通過(guò)向系統(tǒng)中所有一致性控制器廣播GetS請(qǐng)求來(lái)獲取目標(biāo)的cache line,并且當(dāng)前l(fā)ine的owner的控制器需要提供所需數(shù)據(jù)去響應(yīng)請(qǐng)求者。相反,在目錄協(xié)議中,cache控制器通過(guò)向特定的目錄控制器發(fā)送單播GetS請(qǐng)求,目錄控制器可能直接響應(yīng),也可能將請(qǐng)求轉(zhuǎn)發(fā)給其它一致性控制器去響應(yīng)請(qǐng)求者的line數(shù)據(jù)。
表3 core對(duì)cache控制器的常見(jiàn)請(qǐng)求
5.總結(jié)
為了彌補(bǔ)訪(fǎng)問(wèn)memory速度太慢引進(jìn)了cache。在多core系統(tǒng)中,每個(gè)core可能都有自己的私有cache,多個(gè)core會(huì)對(duì)自己的私有cache進(jìn)行讀寫(xiě)操作,如果不使用軟件或硬件來(lái)維護(hù)cache數(shù)據(jù),必然會(huì)造成cache一致性問(wèn)題。為了從硬件層面解決這個(gè)問(wèn)題,現(xiàn)在大多數(shù)多core系統(tǒng)中都定義了一致性協(xié)議,讓各個(gè)一致性控制器遵照“ Single-Writer, Multiple-Read”和“ Data-Value”這兩條原則去維護(hù)存儲(chǔ)內(nèi)容。在一致性協(xié)議設(shè)計(jì)中,根據(jù)core的行為如何通知其它c(diǎn)ore分為監(jiān)聽(tīng)協(xié)議和目錄協(xié)議,根據(jù)core決定寫(xiě)cache line時(shí),如何處理其它c(diǎn)ore的cache line副本,分為無(wú)效協(xié)議和更新協(xié)議?!氨O(jiān)聽(tīng)協(xié)議和目錄協(xié)議”與“ 無(wú)效協(xié)議和更新協(xié)議”可以?xún)蓛山徊娼M成4種一致性協(xié)議,但目前最常用的是目錄協(xié)議和無(wú)效協(xié)議的組合。隨后抽象出cache line狀態(tài)的四個(gè)主要特征:validity、dirtiness、exclusivity和ownership,以及這四個(gè)特征如何對(duì)應(yīng)到經(jīng)典的MOESI狀態(tài)模型。最后介紹了一致性協(xié)議中常用的一致性transactions,以及core請(qǐng)求如何引導(dǎo)cache控制器發(fā)起一致性transactions。
本文沒(méi)有對(duì)cache狀態(tài)轉(zhuǎn)換(transitions)過(guò)程過(guò)多講述,也沒(méi)有講述異構(gòu)系統(tǒng)和多芯片多處理器的一致性,現(xiàn)在計(jì)算機(jī)系統(tǒng)主要是異構(gòu)的,不僅包含多core,還包含GPU和其它加速器(例如,神經(jīng)網(wǎng)絡(luò)硬件)。為了追求可編程性,這些異構(gòu)系統(tǒng)也開(kāi)始支持共享內(nèi)存。
希望本文能幫助大家了解更多的cache一致性知識(shí)。今天就寫(xiě)到這里,后續(xù)會(huì)介紹memory consistency model,敬請(qǐng)期待。
本文轉(zhuǎn)載自微信公眾號(hào)「專(zhuān)芯致志er」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系專(zhuān)芯致志er公眾號(hào)。