什么時候需要cpu_relax()鎖
時間:2021-09-24 16:03:31
手機看文章
掃描二維碼
隨時隨地手機看文章
[導(dǎo)讀]一個最典型的要使用pu_relax()鎖的場景是忙等待(也就是死循環(huán)等一個事情的發(fā)生),在內(nèi)核里面有大量的代碼,比如等寄存器狀態(tài):比如做延遲:簡單來說,你如果在內(nèi)核里面寫了忙等待的代碼,都沒有在循環(huán)里面加個cpu_relax()的話,這基本上是一種比較幼稚的表現(xiàn)。根據(jù)內(nèi)核文檔vo...
比如做延遲:
簡單來說,你如果在內(nèi)核里面寫了忙等待的代碼,都沒有在循環(huán)里面加個cpu_relax()的話,這基本上是一種比較幼稚的表現(xiàn)。
根據(jù)內(nèi)核文檔volatile-considered-harmful,cpu_relax()的描述:由此可見cpu_relax()至少具備三大功能:
- 幫著省電;
- 如果是超線程CPU的機器,可以讓渡CPU給其他的線程;因為我這個CPU目前沒什么正經(jīng)事情干,等的時間不如放慢節(jié)奏,讓別人多干點;
- 它是一個編譯屏障,讓volatile變地在內(nèi)核基本沒什么必要。
我們看看它在ARM64的實現(xiàn):
其中"memory"的部分是服務(wù)于屏障功能,而前面的yield符合SMT系統(tǒng)讓渡的語義。在典型的超線程處理器中,每個超線程不是一個獨立的core,所以兩個或者多個超線程之間仍然在競爭一些資源,如果其中一個人調(diào)用了yield,那么它會在爭搶中放慢節(jié)奏,而旁邊的那個兄弟會搶地更多。
PowerPC的實現(xiàn)則是調(diào)節(jié)hardware multi-threading的優(yōu)先級:
當(dāng)然,硬件如果不具備這種超線程能力的話,cpu_relax()可以簡單地是一個編譯屏障,比如arch/alpha/include/asm/processor.h中:
#define cpu_relax() barrier()
在arch/x86/include/asm/vdso/processor.h的實現(xiàn)中:
REP NOP這種pause操作既可以省點,有可以避免忙等的CPU瘋狂去搶總線訪問內(nèi)存。如果純粹地不加pause暗示的忙等,瘋狂執(zhí)行指令,應(yīng)該是很耗電的,忙等中拼命訪問內(nèi)存,總線沖突也大。
總之,不管具體的體系架構(gòu)怎么實現(xiàn),忙等里面都適合加cpu_relax(),畢竟內(nèi)核多數(shù)的代碼要求是跨平臺的。