perf工具
1、查找耗時點、cache-misses、L1-dcache-load-misses
perf top -C x
perf record -g -e cpu-clock -F 99 -p xxx
perf report --- 函數、匯編
perf record -e L1-dcache-load-misses,cpu-clock -C 3 sleep 10
perf report --stdio | grep XFWD
perf report --stdio | grep acl
最近參與了acl性能優化的方面的工作,目前優化過程接近尾聲,過程中走了不少彎路,當然也學習到了很多性能優化的方法,現在做下總結。
大多說優化基本都是對軟件的優化,所以這里不談硬件優化。
一般軟件涉及到性能問題,首先要確認性能點出在哪里?我們可以使用perf工具來跟蹤系統的性能,也可以來跟蹤某個進程的性能耗時點,是一個非常棒的性能分析工具。這里可以首先定位到哪個函數耗時,進而定位到業務流程上。
優化的過程有這么幾個,首先是對算法的優化,也就是根據業務邏輯功能來分析現有算法是否最優,這么多年的經驗來看,無非是CRUD,既然涉及到性能,一定是一個動態的過程,根據上面的函數就可以知道這個函數時發生在哪個階段。比如發生在查找階段,那么如果查找的數據結構是鏈表,改成hash或者樹結構那效率肯定明顯提升,具體的hash種類及樹結構的種類下面會詳細介紹。其次才是代碼實現細節的優化,這個時候還可以使用perf來看下耗時的原因是什?那影響代碼性能的點有這么幾個:首當其沖的是緩存cache-miss、就是要訪問的數據不再cache里,要到內存或者磁盤上獲取。這里的cache理論知識不再這里講解,本章節只對性能優化的步驟方法進行總體的闡述。那么如何降低cachemiss,可以到下面看詳細過程。有一點要重視,cachemiss不可能完全消除,不要太固執。其次可以在內存、耦合、開棧、指令、寄存器、延遲計算、提前計算等方面
優化角度:架構、算法、代碼。軟件&硬件。
這里不討論硬件優化,以及架構優化,因為這個都是系統級別的,不是可以輕易優化的。
了解業務 ------- 優化算法 或 設計新算法 ---------- 優化代碼
首先要對業務有非常通透的理解,因為大多數代碼首次開發或者架構設計的時候受項目進度約束,並非最完美的,了解了業務,同時明確目前的代碼實現,
這樣就可以找出當前的代碼存在冗余的部分,可以除去不必要的處理,或者合並部分處理過程。甚至設計新的算法。算法確認最優后,其次才能對代碼細節做優化。
算法優化:線性表-----鏈表------哈希-----樹
棧、隊列:這兩個一般是功能型的結構,不涉及性能。
線性表:定義的數組、開辟的連續內存
鏈表:指針、向量
哈希:bihash、多級hash
樹:二叉樹、
平衡二叉樹:搜索性能好
紅黑樹: 插入刪除動態調整的性能好
以上適用於數據較小,完全可以放在內存中。
=================================================
B樹:多叉樹
B+tree:數據都在葉子結點,平衡查找速度
B*tree:可指向兄弟節點,減少分裂。
以上適用於數據庫等數據量較大,需要放在磁盤上。
=================================================
tire樹:每個節點保存一個元素,空間換時間
radix樹:相比於trie樹,壓縮了中間節點,不止保存一個元素。
適用於字符查找,或者有規律的編碼結果進行快速查找
=================================================
代碼優化方法:
內存角度:大頁表(TLB、大頁內存):訪問內存,要查頁表,加速查表。
緩存角度:cache優化(i-cache、d-cache、對齊)、數據預取(連續內存、適度預取)
耦合角度:高內聚低耦合(相關代碼放在一起)、減少冗余代碼
開棧角度:減少調用層次 、inline、宏構造函數、
指令角度:循環展開(指令預取相關)、分支預測(likely)
其他:寄存器參數、延遲計算、提前計算
拓展:多核、多線程、共享數據、讀寫分離、異步、並發、上下文切換、內存池、
問:為了減少函數調用層次,減少開棧時間,而把一個函數寫的較大,