介紹一個比較進階的效能議題 - False Sharing,先分享兩篇文章:

False Sharing 是一種開發時不易意識到的效能陷阱,只發生於多執行緒環境。當兩個或多個執行緒分別存取同一物件或資料結構上的不同變數,直覺上各取各的不會互相干擾也不需 lock 保護。事實上,CPU 多核各自擁專屬 L1/L2 Cache,Cache 以 Cache Line 為管理單位,每條 Cache Line 長度固定(多為 64 Bytes),每次由記憶體搬移資料時,記憶體位置相臨的多個變數會被放進同一條 Cache Line,若在兩次讀寫間 Cache Line 上其他變數被其他執行緒修改,Cache Line 資料即告失效(Cache Miss) 必須從記憶體重新讀取。若多執行緒輪流更新同一條 Cache Line 的多個變數,則這些執行緒永遠無法使用 Cache 加速(因為同一 Cache Line 的其他變數被其他執行緒改了又改改了又改),每次都得從實體記憶體重新讀取,嚴重拖累效能。

不過,此一效能問題並非普遍存在,只有在少數極端情境才會被突顯 - 多條執行緒以極高頻率反覆更新記憶體位置相臨的不同變數。

解決 False Sharing 最有效的手段是在資料結構塞入填充內容, 讓每個變數都單獨佔用一條 Cache Line,即可避免交互干擾。

看完以上說明,是不是覺得這玩意真他X的抽象,有夠難懂?

一時手癢,想起好久沒有寫 jQuery 了,便寫了以下的動態展示網頁,當作久違的 jQuery 伸展操。

第一段影片展示 False Sharing 是怎麼發生的:(實務上 Cache 區分 L1/L2/L3 三層,但原理相同,展示時只以一層說明之)

False Sharing 發生原因

第二段影片展示 Padding 如何避免 False Sharing:

如何使用 Padding 技巧防止 False Sharing

希望能幫助沒聽過的同學認識它。

實務上,在極端苛求效能的情境下才會考量到這層,與 DB、網路呼叫延遲相比,這個效能差距只是奈米等級,是台積電才要關心的事,如果你是 Samsung、hTC、Nokia,暫時可以不用煩惱怎麼對付它.

False sharing is a advanced perfomance pitfall in multithreading. It's a liitle hard to understand, so I write a HTML with jQuery anmiation to demostrate it as a practice.


Comments

# by Vandenberg

其實 False Sharing 的 root cause 在大學一般計算機結構或組織的課程中就有提到,而且標記記憶體區塊已修改的符號叫 dirty bit,只是大多數的人畢業後都還給老師惹。

Post a comment