1逾条、基本概念
現(xiàn)代CPU為了提升執(zhí)行效率厂庇,減少CPU與內(nèi)存的交互(交互影響CPU效率),一般在CPU上集成了多級緩存架構(gòu)迷帜,常見的為三級緩存結(jié)構(gòu)物舒。于是當(dāng)從內(nèi)存中讀取數(shù)據(jù)時,并不是只讀自己想要的部分戏锹。而是讀取足夠的字節(jié)來填入高速緩存行冠胯。根據(jù)不同的 CPU ,高速緩存行大小不同锦针。如 X86 是 32BYTES 荠察,而 ALPHA 是 64BYTES 。并且始終在第 32 個字節(jié)或第 64 個字節(jié)處對齊奈搜。這樣悉盆,當(dāng) CPU 訪問相鄰的數(shù)據(jù)時,就不必每次都從內(nèi)存中讀取馋吗,提高了速度焕盟。 因為訪問內(nèi)存要比訪問高速緩存用的時間多得多。
級別越小的緩存绿渣,越接近CPU, 意味著速度越快且容量越少次企。
CPU1 修改了那個字節(jié),被修改后禽拔,那個字節(jié)被放回 CPU1 的高速緩存行刘离。但是該信息并沒有被寫入 RAM 。
CPU2 訪問該字節(jié)睹栖,但由于 CPU1 并未將數(shù)據(jù)寫入 RAM 硫惕,導(dǎo)致了數(shù)據(jù)不同步。
MESI 是指4中狀態(tài)的首字母努咐。每個Cache line有4個狀態(tài),可用2個bit表示殴胧,它們分別是:
緩存行(Cache?line):緩存存儲數(shù)據(jù)的單元渗稍,一般為64Byte。
2.cache分類:
前提:所有的cache共同緩存了主內(nèi)存中的某一條數(shù)據(jù)。
下圖示意了凯肋,當(dāng)一個cache line的調(diào)整的狀態(tài)的時候,另外一個cache line 需要調(diào)整的狀態(tài)汽馋。
假設(shè)有三個CPU A、B豹芯、C悄雅,對應(yīng)三個緩存分別是cache a、b铁蹈、 c宽闲。在主內(nèi)存中定義了x的引用值為0。?
CPU切換狀態(tài)阻塞解決-存儲緩存(Store Bufferes)
value?=?3;void?exeToCPUA(){??value?=?10; ??isFinsh?=?true; }void?exeToCPUB(){??if(isFinsh){????//value一定等于10囚痴?叁怪! ????assert?value?==?10; ??} }
這種在可識別的行為中發(fā)生的變化稱為重排序(reordings)鸦难。注意根吁,這不意味著你的指令的位置被惡意(或者好意)地更改。
它只是意味著其他的CPU會讀到跟程序中寫入的順序不一樣的結(jié)果合蔽。
void?executedOnCpu0()?{????value?=?10;????//在更新數(shù)據(jù)之前必須將所有存儲緩存(store?buffer)中的指令執(zhí)行完畢榴都。 ????storeMemoryBarrier(); ????finished?=?true; }void?executedOnCpu1()?{????while(!finished);????//在讀取之前將所有失效隊列中關(guān)于該數(shù)據(jù)的指令執(zhí)行完畢待锈。 ????loadMemoryBarrier(); ????assert?value?==?10; }