Linux C++怎麼做框架的性能調優?
在鵝廠某個部門實習,剛實習就安排做框架的優化,分配了一個模塊讓進行優化,一開始優化工具都不會,然後慢慢學會了後優化性能提升並不是很大.請問對框架進行優化需要掌握哪些知識跟工具?
首先還是需要定位系統瓶頸,這步最關鍵:
1. 先看下系統資源消耗情況,看是否資源已經到瓶頸。是CPU ,網路, 還是磁碟IO 哪個已經到瓶頸了,然後有針對的優化。
2. 然後用prof找瓶頸。比如gprof pprof,可以初步看耗時比較多的函數調用和他們之間的關係.3. 大多數情況下工具都不太好使,資源都沒有耗盡,性能還是上不去,這種情況一般是加鎖導致衝突或者有串列執行的代碼成為系統瓶頸,只能自己打trace日誌,把代碼執行的整個流程的關鍵執行段的執行時間都打出來。
再就是針對瓶頸優化,這有很多方法,例如有鎖換無鎖的數據結構,串列改並行,網路的話同步改非同步加大並發,小數據量交互改成緩存批量發送,內存的話減少內存拷貝,特別是大段內存拷貝,避免直接使用glibc的malloc,使用jemalloc和tcmalloc 之類,磁碟的話把隨機讀寫改成順序大批量讀寫。
profiling → 優化瓶頸 → profiling → 優化瓶頸 → profiling → 優化瓶頸 → ……
能想到的,諸如使用更優的演算法、減少內存拷貝、盡量少用鎖、減少頻繁的內存分配和釋放、編譯器優化……
動態追蹤
先從這四個字入門吧。
建議買一本《性能之巔》,就是搞出火焰圖的大牛寫的。c++推薦用intel的vtune。很好奇是什麼樣的框架要優化。實在不行把架構改了 hhhh
框架優化的核心是找bug和找瓶頸,並用更好的方案解決掉存在的問題。例如:我廠的網路層最早是基於boost asio庫的,後重寫了asio庫的整個發送過程,主要的原因是:
A. 測試中發現存在傳送1GByte以上數據時,存在斷線的概率,斷線時TCP/IP底層有檢測到錯誤,
仔細反覆測試,確認TCP/IP在linux的底層實現存在一個小BUG, 是寫緩衝區的容量使用方面,實際使用的時候,並不能夠長期將寫緩衝區用滿,否則會出現故障A.目前我們是使用到80%解決. B. 另外就是Boost庫傳送一組多個獨立std::string塊數據時,存在crash的風險,而成組成批在一條系統調用中發送多條std::string數據,可以減少系統開銷,實現更高的性能.
這一塊現在已經實現了多組數據塊一次性打包傳送到系統態,大大提高了大量多組數據包的發送效率,減少了系統開銷.
這塊性能的提升還是比較明顯的. C. 參考了DPDK 的實現思路,在一些情況下,使用輪詢比epoll的性能高,使用了一個定時器在適當的時候切換到輪詢工作模式,實現了更低開銷. D. Boost asio io_service存在一定的效率問題.寫了一個類似功能的io_service作為輔助,性能比boost庫的實現提升了5倍 重寫後,解決了boost庫的BUG,繞過了TCP/IP的缺陷, 發送性能相比Boost庫有大幅度的提升
一般 Linux 上的性能優化可以用以下工具:
1.valgrind + kcachegrind. Callgrind 和 cachegrind 是valgrind 中性能分析的好工具,而 kcachegrind 則兩者輸出結果的查看工具。
2.intel 出品的 vtune 也是相當不錯的圖形化性能分析工具,相對於 valgrind 來說主要的優點是幾乎不影響程序的性能。3.perf 來自內核開發者的性能分析工具,有一個叫 sysprof 的圖形化界面。過程一般就是用以上工具分析程序中的熱點,然後結合實際代碼看代碼成為熱點的原因,比如:使用了低效的演算法,多線程競爭嚴重,cache 命中率低等。改進代碼之後再童新做性能分析,迭代以上過程直到性能滿足要求為止。
先用火焰圖看一下,再具體問題具體分析
brendangregg/FlameGraph
感謝 @方正 兄弟邀請!
你這個問的很泛,所以只能泛泛的講。
優化模塊最關鍵的是找到性能瓶頸或者設計不合理的地方,把架構圖畫出來,每個子模塊的各個參數和閥值看下,然後進行有針對性的優化。這些方法論在你們內部的知識管理平台上面應該是滿滿的硬貨了,多看多問。
另外,下面是兩個我個人覺得不錯的開放資源:
騰訊移動品質中心
Tencent/libco
希望能對你有幫助。
加油:)
讓實習生做優化,這家廠要麼快要關門了,要麼實在無事可做了。
也陸陸續續做過一些優化,簡單說說,並不一定適合你。
- 緩存是王道,緩存是王道,緩存是王道,在高並發時,nosql也扛不住,簡單的先緩存下再存nosql,性能直接指數級提高。
- 框架性的優化,不整體理解框架感覺很難優化,我這邊都是從整體理解,根據業務或者運算,提高一些操作的優先順序,合併一些操作,避免重複操作等。
- 上面提到的profile等工具,我都是上面這些優化做完了才做的,如果是有經驗的寫的代碼,效果提高不明顯。
PS:std::string效率極其慢,比你想像的還要慢。
先給模塊加壓,搞到快撐不住的時候看看哪個資源是瓶頸,然後針對瓶頸出現的地方優化!
x86下,rdtsc是個好指令。
先要把模塊運行的流程弄清楚,找出各個關鍵點,了解實現細節。根據你了解的實現細節,找出主要耗性能的部分,尋求更好的解決方案。做優化不是上來就依靠工具,工具只有在你確定了問題點之後才是有效的,你現在需要做的是找到問題點,再用工具具體去跑去調。
跟著IDE走
老哥,你問錯地方了,來這可能會收到一堆裝逼答案,還是問導師吧
推薦閱讀: