最近終於抽空把內存篇更新完了,我分享出來的這些問題,其實都是我以前沒有搞的特別明白的困惑。剛剛開始的時候,可能就是在我腦子裏蹦出的一個疑問,好比內存隨機IO會比順序IO慢嗎? 爲了解開這個疑惑,我曾經在網上各類搜索,也去到過國家圖書館翻書,動手搞代碼進行性能測試。最終總算是給了本身一個相對比較滿意的答案,終於在今年我抽空給你們分享了出來。
node
在這個解惑過程當中,我愈來愈深地感覺到國內的技術圈的特色。那就是特別熱衷於應用層的技術,特別喜歡談一些新的概念,好比你去一個技術峯會看看,都是各類高大上的概念,不拽幾個時髦的名詞出來都生怕別人不知道本身技術實力。 這些自己倒沒有錯,我想說的是你們好像廣泛對於底層的一些基礎能力不過重視,當我真正想搜尋一些最基礎的硬件、Linux內核相關的內容時,發現資料太少,不是很容易獲取到。緩存
我是以爲做爲一個技術人應該先去紮紮實實的磨練本身底層的知識。這就比如一個武林新人想要成爲蓋世大俠的話,必須先修煉的是本身的內功,外功呢也重要,不過優先級應該在內功以後。 只有你具有極其深厚的內功,你學習各類新技術,理解各類新概念纔可以駕輕就熟。這也是我把個人這些分享命名成《開發者內功修煉》的緣由。修建一棟大樓確定也是從挖地基開始,沒見過那棟百米高樓是直接平地開始建的。性能優化
按照慣例,再對內存篇全部相關的文章進行一下總結。服務器
1第一部分:物理篇網絡
在這一部分裏,分享的三篇文中主要集中在對內存的物理構成理解上。
數據結構
在這篇文章中,主要目的是借用內存對齊這個技術人耳熟能詳的東東來幫助你們理解內存條內部的物理構成,以及內存是怎麼配合總線來給CPU傳輸數據的。ide
2.《內存隨機也比順序訪問慢,帶你深刻理解內存IO過程》函數
機械硬盤通常咱們都知道的隨機IO慢的很可怕,由於你們都或多或少有過複製文件特別慢的體驗。可是對於內存,絕大部分人就一個印象,快!內存隨機IO慢?沒據說過。但實際上,內存條的隨機IO也比順序IO慢3-4倍。性能
這篇文章是爲了讓大夥明白你的新內存條之因此比較快的緣由,內存數據頻率是經過技術手段放大出來的。但其實這些放大手段都有一些侷限性。好比你的內存數據存儲並不連續,這時候DDR二、DDR3的數據預取對你幫助並不大。再好比你的進程數據都存在一個Bank Group裏,你的進程內存IO就根本不會達到DDR4廠家宣傳的速度。
2第二部分:動手測試
在第一部分裏搞清楚一些基本原理後,我又動手搞了一些實際測試。只有你實際操做親身體會過的東西,纔會真正理解。
在這篇文章裏咱們實驗了在各類狀況下內存訪問延遲的表現。最快的狀況下其實不是內存在IO,而是CPU的高速緩存在工做。穿透到內存的話,順序IO延時大約在10ns左右,隨機訪問確實比順序訪問慢的多,大概是4倍的關係。
咱們在買到一臺新服務器的時候,每每廠家會告訴你他家的內存帶寬能達到8GB/s、25.6/GB/s。可是在實踐中你的內存很難可以達到理想工做狀態,考慮到你的訪問可能不是順序IO,內存條存在CL、tRCD、tRP延遲,再加上可能跨QPI總線的延遲。因此你的應用程序裏內存的帶寬也就達不到廠家的宣稱值。我拿一條廠家宣稱8.5GB/s的內存條進行測試後發現,最壞狀況下其帶寬表現只有474M。
無論啥行業的商家都喜歡用理想狀態下的值來誘導你進行消費。我又聯想到了目前火熱的電動汽車的官方宣稱續航測試條件,車上只坐一我的,路上沒風,路上沒坑,勻速運動,不剎車,不加速,汽車周圍環境溫度要溫馨,不能太冷。。。
現代的服務器裏,CPU和內存條都有多個,它們之間目前主要採用的是複雜的NUMA架構進行互聯,NUMA把服務器裏的CPU和內存分組劃分紅了不一樣的node。屬於同一個node裏的CPU和內存之間訪問速度會比較快。而若是跨node的話,則須要通過QPI總線,整體來講,速度會略慢一些。。
3第三部分:實踐應用
可能不少在應用層作開發的人都或多或少的以爲把內存原理理解到這麼底層沒有啥必要。由於你們手頭的開發工做可能已經被封裝過好幾層了。首先操做系統就封裝了第一層,對用戶進程只暴露申請、釋放等函數,把高速緩存IO、內存IO都封裝成黑盒讓你使用。其次如今的開發語言,如PHP、Java等連內存申請、垃圾回收都不用開發者作了,用的時候直接用。
我這裏經過三個例子說明一下,若是你能深層次理解硬件、Linux內核工做的話,你對新技術認知的層次,你對手頭項目的性能開銷的理解都會有極大的幫助。
這裏我舉了幾個PHP7內核裏的幾個數據結構的優化,由於做者大牛深諳CPU與內存的工做原理,表面上看起來只是幾個字節的節約,可是實際上爆發出了巨大的性能提高。
在這篇文章中,經過將內存的離散的隨機IO變成順序IO,讓內存工做在最舒服的狀態,進而達到了不少倍的讀取性能的改進。
哦,等等。差點忘了一個,在NUMA時代的今天,單進程最大能夠用到多少內存?傳說中的NUMA陷阱長什麼樣子,《挑戰Redis單實例內存最大極限,「遭遇」NUMA陷阱!》來告訴你。
好了,內存篇就給你們分享到這裏,接下來我會逐步整理我在硬盤、網絡方向的思考再給大夥分享出來,提早祝你們2020年新年快樂!