性能優(yōu)化技巧之必備知識
性能優(yōu)化這個話題可大可小。從大的方面來說,在系統(tǒng)設(shè)計之初,需要考慮硬件的選擇,操作系統(tǒng)的選擇,基礎(chǔ)軟件平臺的選擇;從小到方面來說,每個子系統(tǒng)的設(shè)計,算法選擇,代碼怎么寫,如何使用編譯器的選項,如何發(fā)揮硬件的***性能等等。本系列關(guān)注的是在給定硬件平臺,給定操作系統(tǒng)和基礎(chǔ)軟件平臺的情況下,如何優(yōu)化代碼,簡而言之,就是關(guān)注小的方面。
在給定硬件平臺的情況下,如何發(fā)揮硬件的***效能?前提是需要對硬件平臺很熟悉。如何分離硬件相關(guān)代碼和硬件無關(guān)的代碼是一個很重要的技能。針對某一硬件平臺優(yōu)化固然是好,但是如果代碼都是硬件相關(guān)的,就失去了可移植性,軟件的性價比不一定高。
性能優(yōu)化只是系統(tǒng)的一個方面,它會和系統(tǒng)的其他要求有沖突,比如
- 可讀性:性能優(yōu)化不能影響可讀性,看起來不怎么漂亮的代碼,沒有人愿意維護
- 模塊化:性能優(yōu)化往往需要打破模塊的邊界,想想這是否值得
- 可移植:隔離硬件相關(guān)的代碼,盡量使用統(tǒng)一的API
- 可維護:許多性能優(yōu)化的技巧,會導(dǎo)致后來維護代碼的人崩潰
需要在性能優(yōu)化和上述的幾個要求之間做出tradeoff,不能一意孤行。
性能優(yōu)化的目標(biāo)是什么?不外乎兩個:
- 時間性能:減小系統(tǒng)執(zhí)行的時間
- 空間性能:減小系統(tǒng)占用的空間
那么我們優(yōu)化的策略,首先就是對系統(tǒng)進行分解,測量:
- 分解:系統(tǒng)包含的子系統(tǒng),執(zhí)行路徑,函數(shù),指令等等
- 測量:每個子系統(tǒng),執(zhí)行路徑,函數(shù),指令所花費的時間和空間
然后,選取執(zhí)行次數(shù)最多,消耗時間最長的函數(shù)進行優(yōu)化(這里需要指出的是,消耗時間最長的函數(shù)并不一定就是優(yōu)化的對象,這個需要放到某個執(zhí)行路徑上去考察,優(yōu)化最常使用的執(zhí)行路徑)。
對于單核和多核的優(yōu)化,有什么不同?以cache miss為例,在單核上
- I-cache miss的原因是什么?一是代碼路徑太長,以至于超出了cache的容量,cache需要替換;二是 多個執(zhí)行路徑之間相互交替,cache需要替換;三是I-cache, D-cache互相踩。(對于i-cache的優(yōu)化,基本上沒有什么可遵循的規(guī)則。最有效的還是:一,減少無用的代碼;二,減少冗余的代碼;三,減少函數(shù)調(diào)用的開銷;4,快速路徑短小精干,相關(guān)代碼相鄰;5,相關(guān)代碼放到一個段里面等等)
- D-cache miss的原因是什么?一是數(shù)據(jù)結(jié)構(gòu)太大,超出了cache的容量(大數(shù)組,長鏈表都會有這個問題,比較之下,還是數(shù)組更讓人放心一點);二是多個數(shù)據(jù)結(jié)構(gòu)之間相互踩(問題是一個執(zhí)行路徑,需要訪問那么多數(shù)據(jù)嗎?如果是,這個路徑是不是太復(fù)雜了一點);三是D-cache和I-cache的沖突(這個不好說,系統(tǒng)里面會出現(xiàn)這種模式的cache miss嗎?)
在多核上,cache miss會有什么新的特點?
- I-cache miss:多核有獨立的L1 cache,共享的L2/L3 cache。如果多條執(zhí)行路徑同時進行,cache的沖突幾率就會增大。但是這是沒辦法的事情,總不能什么事都不做吧。所以,對i-cache的優(yōu)化,關(guān)注快速路徑就可以了,不要把精力都花費在這個上面
- D-cache miss:鎖,原子操作,偽共享等都會引起多核上的D-cache miss。這是多核優(yōu)化時需要關(guān)注的重點。優(yōu)化的策略也很直接,就是盡量減少鎖,原子操作,偽共享等。多核的所有沖突都是由共享引起的,所以要區(qū)分出哪些是必須共享的,哪些是可以per thread的。并行優(yōu)化與應(yīng)用有關(guān),需要注意的是,優(yōu)化是否對所有用例都有效?做不好,可能顧此失彼。
性能優(yōu)化必備技能
- 熟悉系統(tǒng)執(zhí)行路徑:可以通過讀代碼或者使用profiling工具學(xué)習(xí)代碼,要思考執(zhí)行路徑上不合理的地方,看看哪里可以減少,哪里可以合并。熟悉系統(tǒng)執(zhí)行路徑是性能優(yōu)化的基礎(chǔ)。
- 熟悉測量工具:順手的工具必不可少
- 常用的代碼優(yōu)化技巧和策略:針對不同的語言,不同的平臺,使用與之相應(yīng)的技巧和策略
學(xué)習(xí)性能優(yōu)化是一個不斷積累的過程,在這個過程中,總結(jié)和學(xué)習(xí)自己用的順手的工具和技巧,不斷嘗試,不斷思考,就會有收獲。
【編輯推薦】
- 性能優(yōu)化技巧之工具選擇
- 性能優(yōu)化技巧之系統(tǒng)層次優(yōu)化
- 新的技術(shù)產(chǎn)業(yè):Web性能優(yōu)化
- Linux網(wǎng)絡(luò)性能優(yōu)化方法簡析
- 網(wǎng)站性能優(yōu)化***實踐