CAS/Interlocked操作的原理

CAS/Interlocked操作的原理

在Intelx86指令體系中,有些運算指令加上lock前綴就可以保證該指令操作的原子性。其原理是CPU執行該指令時發現其前面加lock前綴,就會在總線維持一個硬件信號以阻止其他CPU(或線程)訪問與該指令相同的目標內存地址。(注意是指令目標操作數的內存地址而且這些地址是經過內存對齊過的!)

Interlocked單向鏈表函數(就是一個棧)

  ①使用這項技術要極其小心,因爲旋轉鎖是通過循環實現的,較耗費CPU時間,所以在while中加Sleep,可以改善這種狀況,以避免浪費CPU。當然也可以用SwitchToThread代替,以便讓低優先級的線程也有被調度的機會。

  ②特別要注意的是,在單CPU的機器上要避免使用旋轉鎖,因爲如果這個線程一直在不停循環,對CPU浪費大,也影響了其他線程改變鎖的值,造成惡性循環。

  ③使用旋轉鎖的線程優先級要相同,否則如果等待鎖的線程優先級高,則使用資源的線程可能會因分配不到CPU時間而無法釋放鎖。所以使用這種鎖的線程要通過SetProcessPrirityBoost(或SetThreadPriortyBoost)來禁用系統動態提升線程優先級

  ④要確保鎖變量和鎖所保護的數據位於不同的高速緩存行(cache line),如果在同一高速緩存行,當使用資源的CPU更改了被保護的數據,會也會其他CPU相應的高速緩存行失效,這裏等待鎖的CPU還要從內存中(注意:不是CPU高速緩存行)讀入鎖的狀態,這浪費了CPU時間。

  ⑤旋轉鎖是假定被保護資源始終只會佔用一小段時間。與切換到內核模式的等待相比,這種通過循環方式的等待效率更高

volatile限定符會告訴編譯器不要對變量進行優化,而是每次讀取該變量時都從內存中獲取(有時爲了提高效率,編譯器會變量放到某個寄存器,以便快速訪問。這在單線程可能沒有問題,但多線程中,這個內存中的變量可能被修改,而出現寄存器的那個變量與內存變量值的不一致,volatile會強迫總是從內存中讀取而不優化)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章