高并發(fā)(一)

高速緩存和主存的關(guān)系? 二級緩存會比一級緩存更大 但是會更慢

我們?yōu)槭裁葱枰彺妫?/p>

因為CPU的處理速度太快 快到內(nèi)存跟不上 這樣在處理的周期內(nèi) 常常我們的CPU需要等待主存 耗費時間 所以緩存出現(xiàn)了 緩存是為了緩解CPU和內(nèi)存之間的速度不匹配的問題

他的結(jié)構(gòu)是cpu->cache->memory

CPU緩存到底有什么意義?

因為緩存不可能會包含主存所有的數(shù)據(jù),那我們的緩存有什么意義呢

1)時間局部性:如果某個數(shù)據(jù)被訪問,那么再不久的將來它很有可能被再次訪問

2)空間局部性:如果某個數(shù)據(jù)被訪問,那么他的相鄰的數(shù)據(jù)也可能被訪問

cpu多級緩存-緩存一致性(MESI)

用于保證多個CPUI cache之間緩存共享數(shù)據(jù)的一直性

當程序在運行過程中,會將運算需要的數(shù)據(jù)從主存復制一份到CPU的高速緩存當中,那么CPU進行計算時就可以直接從它的高速緩存讀取數(shù)據(jù)和向其中寫入數(shù)據(jù),當運算結(jié)束之后,再將高速緩存中的數(shù)據(jù)刷新到主存當中

個簡單的例子,比如下面的這段代碼:

i = i+1;

當線程執(zhí)行這個語句時,會先從主存當中讀取i的值,然后復制一份到高速緩存當中,然后CPU執(zhí)行指令對i進行加1操作,然后將數(shù)據(jù)寫入高速緩存,最后將高速緩存中i最新的值刷新到主存當中

這個代碼在單線程中運行是沒有任何問題的,但是在多線程中運行就會有問題了。在多核CPU中,每條線程可能運行于不同的CPU中,因此每個線程運行時有自己的高速緩存(對單核CPU來說,其實也會出現(xiàn)這種問題,只不過是以線程調(diào)度的形式來分別執(zhí)行的)。本文我們以多核CPU為例

比如同時有2個線程執(zhí)行這段代碼,假如初始時i的值為0,那么我們希望兩個線程執(zhí)行完之后i的值變?yōu)? 但是事實會是這樣嗎?

  可能存在下面一種情況:初始時,兩個線程分別讀取i的值存入各自所在的CPU的高速緩存當中,然后線程1進行加1操作,然后把i的最新值1寫入到內(nèi)存(主存)。此時線程2的高速緩存當中i的值還是0,進行加1操作之后,i的值為1,然后線程2把i的值寫入內(nèi)存(主存)

  最終結(jié)果i的值是1,而不是2。這就是著名的緩存一致性問題。通常稱這種被多個線程訪問的變量為共享變量

   也就是說,如果一個變量在多個CPU中都存在緩存(一般在多線程編程時才會出現(xiàn)),那么就可能存在緩存不一致的問題

CPU中每個緩存行(caceh line)使用4種狀態(tài)進行標記(使用額外的兩位(bit)表示):

M: 被修改(Modified)

該緩存行只被緩存在該CPU的緩存中,并且是被修改過的(dirty),即與主存中的數(shù)據(jù)不一致,該緩存行中的內(nèi)存需要在未來的某個時間點(允許其它CPU讀取請主存中相應內(nèi)存之前)寫回(write back)主存。

當被寫回主存之后,該緩存行的狀態(tài)會變成獨享(exclusive)狀態(tài)。

E: 獨享的(Exclusive)

該緩存行只被緩存在該CPU的緩存中,它是未被修改過的(clean),與主存中數(shù)據(jù)一致。該狀態(tài)可以在任何時刻當有其它CPU讀取該內(nèi)存時變成共享狀態(tài)(shared)。

同樣地,當CPU修改該緩存行中內(nèi)容時,該狀態(tài)可以變成Modified狀態(tài)。

S: 共享的(Shared)

該狀態(tài)意味著該緩存行可能被多個CPU緩存,并且各個緩存中的數(shù)據(jù)與主存數(shù)據(jù)一致(clean),當有一個CPU修改該緩存行中,

其它CPU中該緩存行可以被作廢(變成無效狀態(tài)(Invalid))。

I: 無效的(Invalid)

該緩存是無效的(可能有其它CPU修改了該緩存行)。

local read 讀取本地緩存的數(shù)據(jù)

local write 將數(shù)據(jù)寫到本地的緩存中

remote read 去讀內(nèi)存中的數(shù)據(jù)

remote write 將數(shù)據(jù)寫回到主存中

四種狀態(tài)和四種操作 對應出16種關(guān)系

操作:

在一個典型系統(tǒng)中,可能會有幾個緩存(在多核系統(tǒng)中,每個核心都會有自己的緩存)共享主存總線,每個相應的CPU會發(fā)出讀寫請求,而緩存的目的是為了減少CPU讀寫共享

主存的次數(shù)

一個緩存除在Invalid狀態(tài)外都可以滿足cpu的讀請求,一個invalid的緩存行必須從主存中讀?。ㄗ兂蒘或者 E狀態(tài))來滿足該CPU的讀請求

一個寫請求只有在該緩存行是M或者E狀態(tài)時才能被執(zhí)行,如果緩存行處于S狀態(tài),必須先將其它緩存中該緩存行變成Invalid狀態(tài)(也既是不允許不同CPU同時修改同一緩存行,

即使修改該緩存行中不同位置的數(shù)據(jù)也不允許)。該操作經(jīng)常作用廣播的方式來完成,例如:RequestFor Ownership (RFO)

緩存可以隨時將一個非M狀態(tài)的緩存行作廢,或者變成Invalid狀態(tài),而一個M狀態(tài)的緩存行必須先被寫回主存

一個處于M狀態(tài)的緩存行必須時刻監(jiān)聽所有試圖讀該緩存行相對就主存的操作,這種操作必須在緩存將該緩存行寫回主存并將狀態(tài)變成S狀態(tài)之前被延遲執(zhí)行。

一個處于S狀態(tài)的緩存行也必須監(jiān)聽其它緩存使該緩存行無效或者獨享該緩存行的請求,并將該緩存行變成無效(Invalid)

一個處于E狀態(tài)的緩存行也必須監(jiān)聽其它緩存讀主存中該緩存行的操作,一旦有這種操作,該緩存行需要變成S狀態(tài)

對于M和E狀態(tài)而言總是精確的,他們在和該緩存行的真正狀態(tài)是一致的。而S狀態(tài)可能是非一致的,如果一個緩存將處于S狀態(tài)的緩存行作廢了,而另一個緩存實際上可能已經(jīng)

獨享了該緩存行,但是該緩存卻不會將該緩存行升遷為E狀態(tài),這是因為其它緩存不會廣播他們作廢掉該緩存行的通知,同樣由于緩存并沒有保存該緩存行的copy的數(shù)量,

因此(即使有這種通知)也沒有辦法確定自己是否已經(jīng)獨享了該緩存行

從上面的意義看來E狀態(tài)是一種投機性的優(yōu)化:如果一個CPU想修改一個處于S狀態(tài)的緩存行,總線事務需要將所有該緩存行的copy變成invalid狀態(tài),而修改E狀態(tài)的緩存不需要

使用總線事務

CPU多級緩存-亂序執(zhí)行優(yōu)化

處理器為提高運算速度而做出違背代碼原有順序的優(yōu)化

例如:計算a*b的值 a = 10; b = 200; result = a*b

單核時候,在CPU亂序執(zhí)行優(yōu)化的時候可能變成 b = 200; a = 10; result = a*b

單核處理器時代處理器能夠保證處理器做出的優(yōu)化不會影響結(jié)果,但是多核時代就會造成亂序,使最終結(jié)果錯誤

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容