第十三章 編碼優(yōu)化
緩存:常見(jiàn)的是將循環(huán)內(nèi)可以提前計(jì)算的在循環(huán)外部計(jì)算
預(yù)先計(jì)算:如果將字母全部轉(zhuǎn)化為大寫(xiě)(頻繁調(diào)用)饥侵,可以先將所有字母對(duì)應(yīng)的大寫(xiě)字母存儲(chǔ)下來(lái),然后直接轉(zhuǎn)化即可
降低靈活性:如IP地址,直接給一個(gè)固定長(zhǎng)度的字符存儲(chǔ)
80-20法則:較快常用路徑的速度刚陡,用||或者&&來(lái)增加常用路徑速度陆盘,||就是為真的概率搞得放前面,&&就是為假的概率高放前面
延遲計(jì)算:等變量要用到時(shí)在計(jì)算恤磷,如一變量只if使用面哼,則在在if聲明最好還有就是string放的賦值,直接定義最好扫步,不要先聲明
無(wú)用計(jì)算完成一步對(duì)string對(duì)象的賦值例:
Student::Student(char *nm): name(nm){} //這才是速度最快的
Student::Student(char *nm): {name = nm} //這個(gè)慢魔策。因?yàn)闀?huì)先調(diào)用string默認(rèn)構(gòu)造函數(shù),將nm轉(zhuǎn)化為string系統(tǒng)體系結(jié)構(gòu)
內(nèi)存訪問(wèn)差別會(huì)很大:數(shù)據(jù)若位于緩存中河胎,則訪問(wèn)只需要耗費(fèi)一個(gè)CPU周期闯袒。若位于主存中,則需要消耗8個(gè)CPU周期游岳。
因此政敢,如果一個(gè)類(lèi)中,兩個(gè)變量經(jīng)常一起訪問(wèn)胚迫,則最好將兩個(gè)變量放在相鄰的位置內(nèi)存管理
動(dòng)態(tài)分配和釋放對(duì)內(nèi)存的代價(jià)比較昂貴喷户,從性能角度講,不需要顯式管理的內(nèi)存所產(chǎn)生的代價(jià)要低得多晌区。
被定義成局部變量的對(duì)象存放于堆棧上摩骨。如X *x = new X;與X x;后者代價(jià)更小庫(kù)和系統(tǒng)調(diào)用
了解庫(kù)和系統(tǒng)調(diào)用才能寫(xiě)出高性能的代碼編譯器優(yōu)化
總結(jié):編碼優(yōu)化在范圍上是局部的買(mǎi)并且不需要對(duì)程序的整體設(shè)計(jì)有深入的理解。
最快的代碼是從不執(zhí)行的代碼朗若,按照以下步驟剔除那些代價(jià)高昂的計(jì)算
a 您打算使用該計(jì)算結(jié)果嗎恼五?
b 您現(xiàn)在需要該結(jié)果嗎?
c 您是否已經(jīng)知道結(jié)果哭懈?
有的時(shí)候無(wú)法繞開(kāi)該計(jì)算灾馒,name可以加快計(jì)算速度:
a 該計(jì)算是否過(guò)于通用
b 一些靈活性隱藏在庫(kù)的函數(shù)調(diào)用中。通過(guò)實(shí)現(xiàn)庫(kù)調(diào)用的自定義版本可以提升速度遣总,
不過(guò)這些庫(kù)調(diào)用必須是頻繁的睬罗,否則無(wú)價(jià)值
c 盡量減少內(nèi)存管理調(diào)用的數(shù)量轨功。因?yàn)榻^大多數(shù)編譯器中,這些調(diào)用的代價(jià)高
d 如果考慮所有可能的輸入數(shù)據(jù)容达。則可以發(fā)現(xiàn)20%的數(shù)據(jù)在80%的時(shí)間里出現(xiàn)古涧。
因此可以犧牲其他不經(jīng)常出現(xiàn)的場(chǎng)景為代價(jià)來(lái)提高典型輸入的處理速度
e 緩存、RAM和磁盤(pán)訪問(wèn)的速度差異明顯花盐,應(yīng)該多編寫(xiě)緩存友好的代碼
第十四章 設(shè)計(jì)優(yōu)化
總結(jié):
- 對(duì)于在80%時(shí)間內(nèi)執(zhí)行的20%軟件羡滑,性能通常損失在靈活性上
- 在代碼細(xì)節(jié)中可以利用緩存優(yōu)化代碼,在整個(gè)程序設(shè)計(jì)中也可以算芯,通称饣瑁可以將先前的計(jì)算結(jié)果保存起來(lái)避免大量的計(jì)算
- 對(duì)于軟件的高效性而言,使用高效的算法和數(shù)據(jù)結(jié)構(gòu)是必要條件
- 有些計(jì)算只有在特定條件下才需要熙揍。這些計(jì)算應(yīng)該被推遲到確實(shí)需要它們的路徑上來(lái)完成职祷。過(guò)早的計(jì)算可能被未被使用
- 大型軟件往往會(huì)變得錯(cuò)綜復(fù)雜,混亂軟件的一大特點(diǎn)就是執(zhí)行失效代碼届囚。定期清理失效和僵死代碼可以增強(qiáng)軟件性能
第十五章 可擴(kuò)展性
SMP(對(duì)稱(chēng)多處理器架構(gòu))是當(dāng)前主流的多處理器架構(gòu)有梆,他通過(guò)一條總線連接多個(gè)對(duì)稱(chēng)的處理器和一個(gè)內(nèi)存系統(tǒng)。
總線是SMP架構(gòu)可擴(kuò)展性的薄弱環(huán)節(jié)奖亚,讓每個(gè)處理器都有自己的大緩存可以有效的控制總線的競(jìng)爭(zhēng)Amdahl(順序的任務(wù)中有些不可以并行化)定律給出了一個(gè)應(yīng)用的可擴(kuò)展性上限淳梦,順序化計(jì)算限制了擴(kuò)展性
實(shí)現(xiàn)可擴(kuò)展性的技巧是減少或者消除順序化代碼。一下是達(dá)到這個(gè)目標(biāo)的一些步驟:
任務(wù)分解:將大的任務(wù)分為小任務(wù)昔字,使線程并發(fā)的執(zhí)行這些小任務(wù)
代碼移出:臨界區(qū)應(yīng)該只包含關(guān)鍵代碼爆袍,不直接操作共享資源的代碼不要放在臨界區(qū)內(nèi)
利用緩存:有事,通過(guò)緩存之前訪問(wèn)過(guò)的數(shù)據(jù)作郭,可以消除對(duì)臨界區(qū)的訪問(wèn)
無(wú)共享:如果需要少量陨囊、數(shù)目固定的資源實(shí)例,可以不使用公共資源池夹攒≈┐祝可以將這些資源實(shí)例設(shè)為線程私有,并最后回收
部分共享:有兩個(gè)一樣的資源池可以減少一半的競(jìng)爭(zhēng)
鎖粒度:不要用同樣的鎖來(lái)保護(hù)所有的資源咏尝,除非這些資源是同時(shí)更新的
偽共享:不要在類(lèi)定義里吧兩個(gè)使用頻度都很高的鎖放太靠近压语,因?yàn)榭梢猿霈F(xiàn)他們共享同一個(gè)緩存行并觸發(fā)緩存一致性風(fēng)暴
驚群現(xiàn)象:仔細(xì)分析您的鎖調(diào)用的特征。當(dāng)鎖被釋放時(shí)编检,是所有的等待線程都被喚醒還是只喚醒一個(gè)胎食,喚醒所有線程會(huì)威脅到應(yīng)用的可擴(kuò)展性
系統(tǒng)和類(lèi)庫(kù)調(diào)用:考察這些調(diào)用的實(shí)現(xiàn)特征。他們有可能是隱藏了順序化的代碼
讀/寫(xiě)鎖:以讀為主的共享數(shù)據(jù)會(huì)從這種鎖中獲益允懂,使用這種鎖厕怜,可以消除讀者線程之間的競(jìng)爭(zhēng)
第十六章 系統(tǒng)體系結(jié)構(gòu)相關(guān)話題
要使用的存儲(chǔ)器離處理器越遠(yuǎn),訪問(wèn)的所需時(shí)間就越長(zhǎng)。離處理器最近的是寄存器粥航,雖然容量很少琅捏,但是速度很快。
對(duì)寄存器的優(yōu)化對(duì)象程序的性能提升而言是極為有益的虛擬存儲(chǔ)器并不是無(wú)償?shù)牡萑福患舆x擇的依賴(lài)系統(tǒng)管理的虛擬結(jié)構(gòu)可能會(huì)影響性能柄延,而且一般都是降低性能
上下文的開(kāi)銷(xiāo)巨大,請(qǐng)避免上下文切換(線程切換)
雖然內(nèi)部管理異步IO有它的重要作用映之,我們還是認(rèn)為正在到來(lái)的處理及架構(gòu)的變化拦焚,會(huì)使得單個(gè)線程方法在方面的優(yōu)勢(shì)減弱