內存屏障(Memory Barrier)是在計算機體系結構中使用的一種同步機制,用于確保在多線程或多核處理器環境中,對共享內存的操作按照預期順序進行。它們通過強制在特定點執行一些指令來規定內存訪問的順序,并防止內存亂序執行帶來的不一致性問題。
內存屏障分為兩種類型:讀屏障(Read Barrier)和寫屏障(Write Barrier)。
讀屏障用于確保在讀操作之前,所有該讀操作之前的寫操作已經完成。它可以防止指令亂序執行,保證讀取到的數據是最新的。
寫屏障用于確保在寫操作之前,所有該寫操作之前的寫操作和讀操作都已經完成。它可以防止指令亂序執行,保證寫入的數據不會被其他操作覆蓋或丟失。
內存屏障的使用能夠解決多線程或多核處理器中的原子性、可見性和有序性等問題,確保程序的正確性和一致性。在編寫并發程序時,合理地使用內存屏障可以提高程序的性能和正確性。
void foo(void)
{a = 1;smp_mb();b = 1;
}void bar(void)
{while (b == 0) continue;assert(a == 1);
}
https://www.kernel.org/doc/Documentation/memory-barriers.txthttps://www.kernel.org/doc/Documentation/memory-barriers.txt
Consider the following abstract model of the system:: :: :: :+-------+ : +--------+ : +-------+| | : | | : | || | : | | : | || CPU 1 |<----->| Memory |<----->| CPU 2 || | : | | : | || | : | | : | |+-------+ : +--------+ : +-------+^ : ^ : ^| : | : || : | : || : v : || : +--------+ : || : | | : || : | | : |+---------->| Device |<----------+: | | :: | | :: +--------+ :: :
(memory barriers logically act on the dotted line in the following diagram):<--- CPU ---> : <----------- Memory ----------->:+--------+ +--------+ : +--------+ +-----------+| | | | : | | | | +--------+| CPU | | Memory | : | CPU | | | | || Core |--->| Access |----->| Cache |<-->| | | || | | Queue | : | | | |--->| Memory || | | | : | | | | | |+--------+ +--------+ : +--------+ | | | |: | Cache | +--------+: | Coherency |: | Mechanism | +--------++--------+ +--------+ : +--------+ | | | || | | | : | | | | | || CPU | | Memory | : | CPU | | |--->| Device || Core |--->| Access |----->| Cache |<-->| | | || | | Queue | : | | | | | || | | | : | | | | +--------++--------+ +--------+ : +--------+ +-----------+::
Cache 一致性問題出現的原因是在一個多處理器系統中,每個處理器核心都有獨占的Cache 系統(比如一級 Cache 和二級 Cache),而導致一個內存塊在系統中同時可能有多個備份,從而引起訪問時的不一致性問題。Cache 一致性問題的根源是因為存在多個處理器獨占的 Cache,而不是多個處理器。它的限制條件比較多:多核,獨占 Cache,Cache 寫策略。當其中任一個條件不滿足時便不存在cache一致性問題。
?
?
read: 包含要讀取的CACHE-LINE的物理地址
read response: 包含READ請求的數據,要么由內存滿足要么由cache滿足
invalidate: 包含要invalidate的cache-line的物理地址,所有其他cache必須移除相應的數據項
invalidate ack: 回復消息
read invalidate: 包含要讀取的cache-line的物理地址,同時使其他cache移除該數據。需要read response和invalidate ack消息
writeback:包含要寫回的數據和地址,該狀態將處于modified狀態的lines寫回內存,為其他數據騰出空間
?
void foo(void)
{a = 1;smp_mb();b = 1;
}
smp_mb()指令可以迫使CPU在進行后續store操作前刷新store-buffer。以上面的程序為例,增加memory barrier之后,就可以保證在執行b=1的時候CPU0-store-buffer中的a已經刷新到cache中了,此時CPU1-cache中的a 必然已經標記為invalid。對于CPU1中執行的代碼,則可以保證當b==0為假時,a已經不在CPU1-cache中,從而必須從CPU0- cache傳遞,得到新值“1”
?
?