標籤:並發 多線程
Java作為一個跨平台的語言,它的實現要面對不同的底層硬體系統,設計一個中介層模型來屏蔽底層的硬體差異,給上層的開發人員一個一致的使用介面。Java記憶體模型就是這樣一個中介層的模型,它為程式員屏蔽了底層的硬體實現細節,支援大部分的主流硬體平台。要理解Java記憶體模型以及一些處理高並發的技術手段,理解一些基本的硬體知識是必須的。這篇會說一下跟並發編程相關的一些硬體知識。
一個基本的CPU執行計算的過程如下:
1. 程式以及資料被載入到主記憶體
2. 指令和資料被載入到CPU的快取
3. CPU執行指令,把結果寫到快取
4. 快取中的資料寫回主記憶體
這個過程中,我們可以看到有兩個問題
1. 現代的計算晶片都會整合一個L1快取,我們可以理解為每個晶片都有一個私人的儲存空間。那麼當CPU的不同計算晶片要訪問同一個記憶體位址時,該記憶體位址的值會在CPU的不同計算晶片之間有多個拷貝,如何同步這些拷貝?
2. CPU讀寫是直接和快取打交道,而不是和主記憶體直接打交道。因為通常一次主存訪問在幾十到幾百個刻度,而一次L1快取的讀寫只需要1-2個刻度,而一次L2快取的讀寫只需要數十個刻度。那麼CPU寫到快取的值何時寫回到主內?如果是多個計算晶片在處理同一個記憶體位址,那麼如何處理這個時間差是個問題。
對於第一個問題,不同的硬體結構處理的方式不一樣。我們來理解一下互連線的概念。
互連線是處理器於主存以及處理器與處理器之間進行通訊的媒介,有兩種基本的互連接構:SMP(symmetric multiprocessing 對稱式多處理)和NUMA(nonuniform memory access 非一致記憶體訪問)
SMP系統結構非常普通,因為它們最容易構建,很多小型伺服器採用這種結構。處理器和儲存空間之間採用匯流排互聯,處理器和儲存空間都有負責發送和監聽匯流排廣播的資訊的匯流排控制單元。但是同一時刻只能有一個處理器(或儲存控制器)在匯流排上廣播,所有的處理器都可以監聽。
很容易看出,對匯流排的使用是SMP結構的瓶頸。
NUMP系統結構中,一系列節點通過點對點網路互聯,像一個小型互連網,每個節點包含一個或多個處理器和一個本機存放區器。一個節點的本機存放區對於其他節點是可見的,所有節點的本機存放區一起形成了一個可以被所有處理器共用的全域儲存空間。可以看出,NUMP的本機存放區是共用的,而不是私人的,這點和SMP是不同的。NUMP的問題是網路比匯流排複製,需要更加複雜的協議,處理器訪問自己節點的儲存空間速度快於訪問其他節點的儲存空間。NUMP的擴充性很好,所以目前很多大中型的伺服器在採用NUMP結構。
對於上層程式員來說,最需要理解的是互連線是一種重要的資源,使用的好壞會直接影響程式的執行效能。
大概理解了不同的互連結構之後,我們來看看緩衝一致性協議。它主要就是處理多個處理器處理同一個主存地址的問題。
MESI是一種主流的緩衝一致性協議,已經用在Pentium和PowerPC處理器中。它定義了緩衝塊的幾種狀態
- modified(修改):緩衝塊已經被修改,必須被寫回主存,其他處理器不能再緩衝這個塊
- exclusive(互斥):緩衝塊還沒有被修改,且其他處理器不能裝入這個緩衝塊
- share(共用):緩衝塊未被修改,且其他處理器可以裝入這個緩衝塊
- invalid(無效):緩衝塊中的資料無效
展示了MESI快取一致性協議的狀態轉換執行個體。
1. 在a中,處理器A從地址a讀取資料,將資料存入它的緩衝共置為exclusive
2. 在b中,當處理器B試圖從相同地址a讀取資料時,A檢測到地址衝突,以相關資料做出響應。此時a同時被A和B以shared狀態裝入緩衝
3. 在c中,當B要對共用地址a進行寫操作,則將狀態改為modified,並廣播提醒A,讓它將它的緩衝塊狀態設定為Invalid
4. 在d中,當A試圖從a讀取資料,會廣播它的請求,B則把它修改的資料發送到A和主存,並設定兩個副本的狀態為shared來做出響應
更多緩衝一致性協議的細節參考這篇 http://blog.csdn.net/realxie/article/details/7317630
緩衝一致性協議存在的一個最大的問題是可能引起緩衝一致性流量風暴,之前我們看到匯流排在同一時刻只能被一個處理器使用,當有大量緩衝被修改,或者同一個緩衝塊一直被修改時,會產生大量的緩衝一致性流量,從而佔用匯流排,影響了其他正常的讀寫請求。
一個最常見的例子就是如果多個線程對同一個變數一直使用CAS操作,那麼會有大量修改操作,從而產生大量的緩衝一致性流量,因為每一次CAS操作都會發出廣播通知其他處理器,從而影響程式的效能。
後面我們會講如何最佳化這種使用方式。
對於第二個問題,如何處理修改資料從快取到主記憶體的時間差,通常使用記憶體屏障來處理,後面會有專門的主題。
轉載請註明來源:http://blog.csdn.net/iter_zc
聊聊高並發(五)理解緩衝一致性協議以及對並發編程的影響