最近 trace linux kernel 時看到一對 function smp_load_acquire()smp_store_release(), 一直很納悶這跟 read/write memory barrier 有什麼不同。

近年來由於 CPU 與 compiler 的發展,為了提供更高效能,只要資料間沒有 dependency 。 compiler 與 CPU 有可能會對程式執行的過程做 reordering,執行的 sequence 有可能不照你從 source 看到的樣子。尤其在 smp 的情況下,我們通常會加上一些 memory barrier 來防止這樣的 reordering 造成程式計算的錯誤。但這 其實會影響 執行的效能。但為何我們需要另外多兩個函式來做這件事呢?

最近看到一篇 LWN 的 文章,剛好可以解答疑惑,摘錄如下,

  • smp_wmb (write memory barrier):any write operation executed after the barrier will not become visible until all writes executed prior to the barrier are visible.
  • smp_rmb (read memory barrier): any reads executed before the barrier are forced to complete before any reads after the barrier can happen.
  • smp_mb:a barrier for both read and write operations

簡單來說 smp_wmb() 主要就是防止 write operation 的 reordering,smp_rmb() 防止 read operation 的 reordering , 而 smp_mb() 則是防止所有 memory access 的 reordering。

x86 提供另一種 CPU 的 support,可以做到

reads are ordered before reads, writes before writes, and reads before writes, but not writes before reads.

基本上除了原本的 read/write barrier 外,針對 read 跟 write 同時發生時的微調(rule: reads before writes)。文中 提到可能有一部份原本的 memory barrier 會改用這個 API 來實作。感覺起來 kernel 這幾年不斷針對 lock 與 barrier 方面進行更細部的控制阿。

後記

後來看了 barrier 相關資訊後發現之前的描述不是很正確,應該說這個 primitive 是屬 於 one way barrier,只確保其中一個方向的 order,主要是確保 critical section 裡的資料與外面可以維持正確的 order。


Viller Hsiao

All about C/C++/Python, Embedded Linux/RTOS, and Web programming