1. 程式人生 > 其它 >多核程式資料同步

多核程式資料同步

多核程式原子性可見性順序性

概念:

多核:是指多個物理核心,這些核心可能在一個物理處理器上,也可能分佈在多個物理處理器。

多核程式需要注意共享資料的同步問題,主要包含

1、原子性:讀寫資料的多次操作不能被中斷。比如a=1,這句話會被編譯為多條彙編指令,這幾條指令執行過程中如果被打斷,可能導致其他程式讀出髒資料,嚴重的導致程式崩潰。

2、可見性:對於多執行緒共享的資料,其中一個執行緒修改了資料,其他執行緒有可能讀到的還是原值,甚至一直讀不到修改後的值。

3、順序性:程式邏輯的順序執行。

下面具體探討這三種現象出現的原因及應對方案:

1、原子性:

編寫程式的一個語句會被編譯為多條編譯指令,被cpu依次執行,共享的資料可能在這些操作未完成之前被其他執行緒讀寫到,同時作業系統也會產生中斷,導致指令的執行不是原子的。

2、可見性:

多核系統中,一般每個核都有自身的快取記憶體(L1、L2級快取記憶體)以及暫存器,這些儲存單元會快取資料以提高效能,這就造成了一個執行緒修改了共享資料後,其他的執行緒並不一定看到。為了解決該問題,硬體層都存在cache一致性協議MESI,保證了共享資料的可見性,但這會嚴重影響處理器效能,因此實際處理器架構中都增加了store buffer之類的結構,這個結構不是cache,因此單單依靠MESI在實際程式設計時已無法保證可見性。

3、順序性

編譯器為了提高程式效能會對程式進行優化,即指令重排,打亂程式設計時書寫的順序,這往往出現在c程式使用-O2級別時。指令重排單執行緒情況下不會出現問題,但對於嚴格依賴共享資料讀寫順序的多執行緒程式,則會出現不可預見的效果。

其次,程式執行時,處理器為了提高利用率,指令可能被亂序執行。以上兩個方面造成多核程式可能不會按照預先設計的順序執行程式語句,導致程式的執行效果和預期不一致,甚至崩潰。

解決方案

1、volatile能保證可見性,順序性,不能保證原子性

2、加鎖能保證原子性、可見性、順序性

3、c++11的atomic配合std::memory_order_seq_cst也能保證原子性、可見性、順序性