多核系統下內存一致性如何保證?


一點 synchronization 都沒有,你的並發編程是從哪兒學的?


這事如果跟題主說「沒有鎖就不對」就太簡單粗暴了。

先說結論:現代x86下的SMP系統的內存一致性屬於弱一致性。一致性幾乎僅僅體現在同一個core可以看見consistant data——自己的寫可以按順序被自己看到,自己的寫,瞬間可以被自己看到。但是多核間並沒有這種一致性——a. core 0寫地址A,core 1可能在未來的任意時刻才能看到變化,除非core 0主動barrier;b. core 0先後寫地址A和地址B,core 1可能在看到B的內容變化時,仍然見不到A的內容發生變化

mfence的保證是:core 0執行mfence後,其餘的core可以看到mfence前的一切變化,但並不保證mfence前的所有變化按照順序被看見。

write A
mfence
write B

上面的代碼可以保證A的變化先於B被其他core發現。

write A
write B
mfence

而這種寫法,也就是相當於你的寫法,並不保證A和B的變化被其他core發現的順序。

--------tl;dr; 華麗的廢話分割線--------

一個可以用來說明現代內存弱一致性的演算法:Peterson"s algorithm

// global data:
int loser;
bool active[2] = {false, false};
int cnt = 0;

core 0:
int i = 0; // private
while (i++ &< 10000) { active[0] = true; loser = 0; while (loser == 0 active[1]); ++cnt; active[0] = false; } core 1: int i = 0; // private while (i++ &< 10000) { active[1] = true; loser = 1; while (loser == 1 active[0]); ++cnt; active[1] = false; }

如果內存強一致,那麼此演算法能夠保證在執行後,cnt == 20000。如果write存在延遲,那麼兩者可能同時看到對方並不active,於是同時執行++cnt,導致最後cnt &< 20000。

下面可以用來說明對內存的寫並不會按照順序被其他core看見:

// bool empty = true;
// uint32_t value = 0;
core 0:
while (empty);
printf("%x
", value);

core 1:
value = 0xdeadbeef;
empty = true;

即使CPU並沒有reorder對於value和empty的寫,此程序仍然不能保證core 0會輸出0xdeadbeef。因為core 1對於empty的修改可以先於對於value的修改到達core 0,導致core 0看到舊的值0而不是deadbeef。


不需要memory fence,cache是透明的,但你需要保證整型讀寫是原子的(特定的原子指令實現可能會同步cache)。


情景:多核應用,core0將數據通過共享DDR3給core1~7處理,並將結果通過pcie傳出, 對16MB的數據,在內存中進行如下的複製操作: 1、通過PCI-E將數據從外部複製到0x81000000, 2、core0將數據從0x81000000複製到0x90000000, 3、core1~7將數據從0x90000000複製到0x84000000, 4、core0將數據從0x84000000到0x83000000, 5、通過PCI-E將數據從0x83000000複製到外部, 導出後跟原始16MB數據對比發現數據不完全一致,但是同樣的操作完全由Core0進行就不會出現錯誤。

最開始內存複製用的memcpy: void copyDDR(int *src, int *dst, unsigned size) { memcpy(dst,src,size); }

後來想到了可能是緩存一致性造成的錯誤,就增加了L2的write-back和invalidate操作,代碼如下,但是還是會出錯: void copyDDR(int *src, int *dst, unsigned size) { CACHE_invL2 ((void *)src,size,CACHE_WAIT); _mfence();

memcpy(dst,src,size);

CACHE_wbL2((unsigned int*)dst, size, CACHE_WAIT);

_mfence();

}

希望我的回答可以幫到您哦


不邀自來,我覺得操作系統的存在就是為了解決內存同步這些問題的,


推薦閱讀:

目前這個這個時代,swap space還有什麼意義?
內存有必要清理嗎?
矢量化操作系統界面,為什麼很難實現?
請問有什麼計科學生可以努力去嘗試的實驗和項目呢?

TAG:操作系統 | Linux | 內存管理 |