提升自旋鎖spinlock的性能-pause指令

看源碼的時候get的一個新的知識點,可以提升自旋鎖spinlock的性能-pause指令,看到的源碼如下:

     #define cpu_pause()         __asm__ (".byte 0xf3, 0x90")
     #define NOP_CPU3(n)     {int i = 0; while(i++ < (n)) cpu_pause();} 
     // 調用代碼
     NOP_CPU3(20);

經過上網查找資料 _asm_ (“.byte 0xf3, 0x90”) intel的pause指令。當spinlock執行lock()獲得鎖失敗後會進行busy loop,不斷檢測鎖狀態,嘗試獲得鎖。這麼做有一個缺陷:頻繁的檢測會讓流水線上充滿了讀操作。另外一個線程往流水線上丟入一個鎖變量寫操作的時候,必須對流水線進行重排,因爲CPU必須保證所有讀操作讀到正確的值。流水線重排十分耗時,影響lock()的性能。

參考這位同學的文章:
自旋鎖spinlock剖析與改進

Pause指令解釋(from intel):

Description
Improves the performance of spin-wait loops. When executing a “spin-wait loop,” a Pentium 4 or Intel Xeon processor suffers a severe performance penalty when exiting the loop because it detects a possible memory order violation. The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. The processor uses this hint to avoid the memory order violation in most situations, which greatly improves processor performance. For this reason, it is recommended that a PAUSE instruction be placed in all spin-wait loops.

提升spin-wait-loop的性能,當執行spin-wait循環的時候,笨死和小強處理器會因爲在退出循環的時候檢測到memory order violation而導致嚴重的性能損失,pause指令就相當於提示處理器哥目前處於spin-wait中。在絕大多數情況下,處理器根據這個提示來避免violation,藉此大幅提高性能,由於這個原因,我們建議在spin-wait中加上一個pause指令。

名詞解釋(以下爲本人猜想):memory order violation,直譯爲-內存訪問順序衝突,當處理器在(out of order)亂序執行的流水線上去內存load某個內存地址的值(此處是lock)的時候,發現這個值正在被store,而且store本身就在load之前,對於處理器來說,這就是一個hazard,流水流不起來。

在本文中,具體是指當一個獲得鎖的工作線程W從臨界區退出,在調用unlock釋放鎖的時候,有若干個等待線程S都在自旋檢測鎖是否可用,此時W線程會產生一個store指令,若干個S線程會產生很多load指令,在store之後的load指令要等待store在流水線上執行完畢才能執行,由於處理器是亂序執行,在沒有store指令之前,處理器對多個沒有依賴的load是可以隨機亂序執行的,當有了store指令之後,需要reorder重新排序執行,此時會嚴重影響處理器性能,按照intel的說法,會帶來25倍的性能損失。Pause指令的作用就是減少並行load的數量,從而減少reorder時所耗時間。

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