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