内存屏障,先看这篇文章
剛看到這個詞的時候,我以為是白內障,然后查了很多資料,才理解內存屏障是干嘛的,我就不像很多其他文章說得那么多了,我希望我說得簡單一些,讓大家看了我的文章都知道這個是怎么回事。
說到內存屏障,我們先從CPU性能優化說起
性能優化的方法一,緩存
CPU的速度很快,到底有多快?我們就用光速來比喻CPU的執行速度吧,反正就是執行讀寫很快,但是CPU速度很快,內存的速度很慢,怎么辦?
這時候,高速緩存出現了「先不抬杠說寄存器哈」。比如有一個變量a ,CPU在很長一段時間內都需要使用它,如果把他放在內存里面的話,每次讀寫的速度都很慢,這樣嚴重拖慢了CPU的執行速度。
所以就出現了 緩存
緩存也是分類的,緩存分成了三類,我簡單說明下
緩存同步協議MESI如果在4個CPU在各自的L1 里面都有一個變量 i ,他們要把這個變量i寫入到內存里面去,是以哪一個為準呢?
這個時候就需要緩存的同步協議,每個cpu對緩存里面的變量操作的時候,要通知其他CPU,讓他們知道當前的狀態。
CPU不僅需要發消息給其他CPU告訴他們狀態,同時也要接收其他CPU發出來的狀態。
這樣做的最終目的,就是為了保證CPU對變量操作的一致性。
CPU性能優化的方法二,運行時指令重排
指令重排是個有意思的事情,如果把CPU當成是一個人的話,他也是有自己的意識的,存在意識的東西,就會存在自己做事情的方法,比如,我今天要去打籃球,還要去幫媽媽打醬油,我是先打籃球還是先打醬油,因為個人的意識不同,做事情的先后順序也存在差異。
為什么出現指令重排?如果有一個CPU,我們假設是CPU0吧,它在寫緩存的的某個區塊的時候,發現這個緩存位置剛好被CPU1正常操作,那他怎么辦?有兩種方法,一種是等待CPU1執行結束后自己再執行,還有一種方法就是先去干其他的事情,很明顯,CPU為了提高自己的性能,它會選擇第二種方法,就是先去干其他的事情,干其他的事情,就出現上面描述的情況,指令重排了。
所以我們會有一個疑問?代碼是按照程序員的想法去執行的呢?還是按照CPU的想法去執行的呢?回答當然是需要按照程序員的意識去執行的。
所以要求,指令重排遵循as-if-serial語義這個是什么意思呢?就是說指令重排的結果不能影響程序員預期的結果,比如上面的代碼,重排后就會出現問題,那么CPU就不能對指令進行重排。
注意,上面所說的as-if-serial語義針對的是單核CPU來說
但是如果是下面的代碼
a = 100; b = c;上面兩條語句不存在依賴關系,它們可以進行指令重排,因為重排后不會影響最后的執行結果。
高速緩存和指令重排序(reordings)存在的問題
緩存機制和指令重排都是為了CPU運算的性能優化。會出現兩個問題。1、緩存和內存的數據并不是時實同步的,同一個內存地址,不同的CPU看到的內存值是不一樣的。因為CPU運行速度很快,假設,CPU0 讀 地址 0x2345 的時候值為 1,這個時候,CPU1向 0x2345寫入了 2,CPU2再讀這個內存 0x2345 的值的時候,發現它變成2了。所以就有問題了。
出現的問題是同一個時間點上,不同的CPU看到的同一個內存地址數據不一樣
2、我們指令重排說的as-if-serial語義只是針對單個CPU,那多個CPU呢?會出現什么問題
看下面的例子:
看上面圖片
CPU0 要執行兩條指令,CPU1也要執行兩條指令,但是如果他們執行的先后順序不同,那么x和y的結果也將存在差異。
第一種情況如下圖執行順序會導致 x = 0 , y = 1。
第二種情況如下圖執行順序會導致 x =1,y = 0。第三種情況如下圖執行順序會導致 x = 1,y=1。
結果跟程序員的預期不符合 出現的問題是,多個CPU,也就是我們經常所說的SMP系統下,會出現結果和預期不一致的問題
最后說內存屏障(Memory Barrier)
內存屏障就是用來解決上面兩個問題的。這個是CPU廠商來搞定的。
寫內存屏障(Store Memory Barrier) 寫內存屏障的意思就是在寫內存的后面加入指令 Store Barrier ,如果CPU有讀的也有寫的,加了這條指令,就保證先執行寫入而不去做指令重排,這種顯示調用可以讓其他線程看到。其他線程會等這個執行結束后再去操作,既然是等待,那也是降低性能的,好吧,降低性能也是沒有辦法的事情了。
就拿上面的 圖片來說明A = 1 B = 1 這兩個是寫操作,我們加上寫內存屏障,即使其他CPU有讀的指令,我們需要等待這個寫完成后,再進行讀操作。
讀內存屏障 (Load Memory Barrier) 在讀指令之前插入Load Barrier,可以讓高速緩存中的數據失效,強制從內存加載最新的數據,讓CPU緩存和主內存保持一致,避免了緩存導致的一致性問題。
總結
CPU為了性能,發明了緩存和指令重排,但是又因為緩存和指令重排出現了新的問題,因為新的問題出現,聰明的人類又發明了內存屏障,之所謂,兵來將擋水來土掩就是這個道理。
文章是整理了自己看到資料的很多見解,后續會發新的文章進一步講解,當然了,或者也會不發,我就是一只漂亮的鴿子,我鴿呀鴿呀鴿,祝大家周末愉快。
掃碼或長按關注
回復「?籃球的大肚子」進入技術群聊
總結
以上是生活随笔為你收集整理的内存屏障,先看这篇文章的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【c++实现】模拟银行叫号系统
- 下一篇: 安装Java反编译工具Luyten(Wi