linux 內核中一個全局變量引發的性能問題


為了調試一個功能,在一個內核模塊中,增加了一個全局變量,用來統計自有skb池的申請情況。

因為是臨時增加,所以沒有考慮性能,一開始只是一個fail的統計,數量不多,也不太考慮是否有計數丟失的情況,畢竟那個賣火車票的例子已經讓很多人知道了並發導致的計數丟失。

因為只是一個簡單統計,這樣做無可厚非。

后來有人維護的時候,增加了一個success的統計,結果發現增加該變量前后cpu占用增加了一個點。為了排除是偽共享的行為,我將兩個變量中間增加了一些reserve的空間,結果還是如此。去掉success統計,立刻恢復。一個簡單的計數居然導致如此的性能變化,只能祭出倚天劍了,perf上馬。

根據perf stat 的統計,我發現 cache-misses這一行有明顯的增長,

最后排查的原因就是,由於是一個多核的設備,每個cpu都會對這個變量進行++,也就是這個變量是一個熱點,當A cpu對其++的時候,根據mesi協議,顯然會發送讓其他cpu對這個變量進行讀緩存失效,並且還需要等待其他cpu的回復的最新的緩存值。雖然這個過程是由硬件實現的,但對性能的影響卻是顯而易見的。

所以將這個統計改成percpu變量,然后需要show的時候,將各個cpu相加起來就ok。犧牲了部分准確性,但提高了性能,因為性能這個詞,本來就是一種權衡,不管是用時間換空間還是空間換時間。

所以多核並發,針對統計類的實現,最好實現成percpu的。這個就是經典的並行拆分思路。

 

 

ps:

推薦對並發編程感興趣的童鞋,可以參考老謝和魯陽翻譯的《深入理解並行編程》。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM