高性能涉及的東西有很多,該怎么才能記住呢?
我覺(jué)得這是一個(gè)很有代表性的問(wèn)題,相信很多人都有類(lèi)似的困惑,所以決定寫(xiě)篇文章來(lái)好好聊聊這個(gè)問(wèn)題。
確實(shí)是這樣,當(dāng)初在準(zhǔn)備高性能相關(guān)的面試問(wèn)題時(shí),也是同樣的感受,有好多東西啊,該想個(gè)什么辦法把它們都串起來(lái)呢?
計(jì)算機(jī)運(yùn)行的本質(zhì),或者說(shuō)程序執(zhí)行的本質(zhì),就是CPU不斷取出內(nèi)存中的指令,然后執(zhí)行它。
在這個(gè)過(guò)程中,CPU需要與內(nèi)存打交道,因?yàn)槌绦蛑噶钤谶@里面;還需要與硬盤(pán)、網(wǎng)卡等一些外部設(shè)備打交道,存儲(chǔ)數(shù)據(jù)、傳輸數(shù)據(jù)。
CPU、內(nèi)存、外部設(shè)備,這三個(gè)是計(jì)算機(jī)最主要的三個(gè)東西,所以我們?cè)谒伎几咝阅艿膯?wèn)題時(shí),圍繞這三個(gè)東西,就可以把很多技術(shù)串起來(lái)。
1、讓CPU執(zhí)行指令更快一點(diǎn)
程序是CPU在執(zhí)行,最容易想到的當(dāng)然就是讓CPU跑的更快一些。這方面主要是涉及硬件技術(shù),跟軟件關(guān)系不大。
比如提高CPU主頻、指令流水線技術(shù)、亂序執(zhí)行、分支預(yù)測(cè)等等。
2、使用緩存
程序運(yùn)行經(jīng)常需要讀取和加載數(shù)據(jù),當(dāng)程序經(jīng)常需要從一個(gè)慢速設(shè)備讀取數(shù)據(jù)時(shí),性能勢(shì)必會(huì)受到影響。所以,可以先把數(shù)據(jù)緩存到一個(gè)能快速獲取的地方,加快數(shù)據(jù)加載速度,然后選擇適當(dāng)?shù)臅r(shí)機(jī)來(lái)更新緩存中的數(shù)據(jù)。
緩存技術(shù)在計(jì)算機(jī)中無(wú)處不在,CPU中有存放數(shù)據(jù)和指令的一二三級(jí)緩存,還有存放內(nèi)存地址翻譯的TLB緩存。
操作系統(tǒng)中的文件系統(tǒng)管理硬盤(pán)數(shù)據(jù)也使用了頁(yè)緩存Page Cache。
后端服務(wù)為了快速獲取數(shù)據(jù),使用Redis/Memcache作為內(nèi)存數(shù)據(jù)緩存,避免每次都從數(shù)據(jù)庫(kù)中查詢(xún)。
瀏覽器中為了加快渲染速度,也有前端資源的緩存,避免每次都找網(wǎng)站服務(wù)器請(qǐng)求。
網(wǎng)站服務(wù)器為了提高響應(yīng)速度,也有CDN緩存。
3、減少CPU被打斷次數(shù)
CPU在運(yùn)行過(guò)程中不是一直埋頭執(zhí)行程序,它時(shí)不時(shí)的會(huì)被打斷,這就是中斷。
最典型的就是網(wǎng)絡(luò)數(shù)據(jù)包處理,如果在很大網(wǎng)絡(luò)流量下,網(wǎng)卡每來(lái)一個(gè)數(shù)據(jù)包都通過(guò)中斷告訴CPU,那CPU一天別干活了,煩都要煩死了。
所以Linux內(nèi)核中的NAPI技術(shù)通過(guò)輪詢(xún)網(wǎng)卡,減少中斷次數(shù)就能顯著提高性能。
另外DMA技術(shù)通過(guò)把數(shù)據(jù)傳輸?shù)墓ぷ魍獍鋈ィ夥臗PU,也是這一思想的應(yīng)用。
4、減少內(nèi)存拷貝
很多時(shí)候,程序需要頻繁拷貝數(shù)據(jù),但拷貝數(shù)據(jù)的過(guò)程時(shí)比較耗時(shí)的,如果能減少拷貝的次數(shù),無(wú)疑會(huì)提高程序性能。
比如內(nèi)存映射、零拷貝技術(shù)就屬于這一類(lèi)技術(shù)。
另外高性能抓包技術(shù)DPDK,讓?xiě)?yīng)用程序直接讀取網(wǎng)卡,減少數(shù)據(jù)拷貝也是這種思想的體現(xiàn)。
5、并行與并發(fā)
這個(gè)思想很直接,一個(gè)人干活忙不過(guò)來(lái),那就多找?guī)讉€(gè)人一起干。并行與并發(fā)的思想同樣在計(jì)算機(jī)領(lǐng)域無(wú)處不在。
如CPU的多核技術(shù),超線程技術(shù)、單指令多數(shù)據(jù)技術(shù)SIMD等。
多線程技術(shù)、NUMA技術(shù)、多節(jié)點(diǎn)負(fù)載均衡技術(shù)等。
后端服務(wù)開(kāi)發(fā)中的I/O多路復(fù)用技術(shù)(select/poll/epoll)。
6、減少鎖的競(jìng)爭(zhēng)
前面提到多線程技術(shù),而提到多線程就離不開(kāi)鎖。很多時(shí)候,線程在鎖的競(jìng)爭(zhēng)上浪費(fèi)了太多時(shí)間,上下文的切換這些都需要有開(kāi)銷(xiāo)。
所以減少鎖的競(jìng)爭(zhēng)也是提高性能的一種方式,這方面的技術(shù)有原子操作、無(wú)鎖編程等。
7、資源池化技術(shù)
很多程序運(yùn)行啟動(dòng)時(shí)就預(yù)先分配好資源,而不是在需要的時(shí)候才去分配,這也是一種提高性能的方法。最常見(jiàn)的有線程池、內(nèi)存池。
8、減少I(mǎi)/O次數(shù)
程序運(yùn)行的時(shí)候經(jīng)常要從硬盤(pán)上讀取數(shù)據(jù),而這類(lèi)操作是非常耗時(shí)的,如果能減少I(mǎi)/O的次數(shù),合并I/O次數(shù),對(duì)性能的提升將是巨大的。
體現(xiàn)這類(lèi)思想的技術(shù)有B+樹(shù)、SQL批量執(zhí)行等。
9、良好的數(shù)據(jù)結(jié)構(gòu)與算法
程序的靈魂是數(shù)據(jù)結(jié)構(gòu)與算法,前面說(shuō)了那么多,即便都做到了,但如果你的數(shù)據(jù)結(jié)構(gòu)和算法設(shè)計(jì)的一塌糊涂那也是白搭。
良好的數(shù)據(jù)結(jié)構(gòu)與算法能夠從根本上解決高性能的問(wèn)題。
這方面思想的體現(xiàn)有哈希表、B+樹(shù)、跳表等。
總結(jié)
上面這幾個(gè)點(diǎn)不是孤立存在的,很多時(shí)候都是互相交織在一起的綜合應(yīng)用。比如零拷貝技術(shù),既是減少內(nèi)存拷貝的思想,也是減少打擾CPU的思想。在I/O多路復(fù)用epoll中,既是并發(fā)思想體現(xiàn),也有減少內(nèi)存拷貝思想的體現(xiàn)。
最后來(lái)總結(jié)一下,下次回答提高性能可以從四個(gè)增加、四個(gè)減少、一個(gè)良好來(lái)展開(kāi):
增加CPU速度、增加緩存、增加并行度、增加資源池
減少內(nèi)存拷貝、減少I(mǎi)/O次數(shù)、減少CPU被打斷次數(shù)、減少鎖競(jìng)爭(zhēng)
良好的數(shù)據(jù)結(jié)構(gòu)與算法
高性能是一個(gè)廣泛的話題,這篇文章也不可能涵蓋所有,如果有遺漏的歡迎大家評(píng)論區(qū)補(bǔ)充交流。
編輯:黃飛
?
評(píng)論
查看更多