Linux核心為大規模支援100Gb/s網絡卡準備好了嗎?並沒有
又是大年初一,和過去三十多年的新年一樣,無聊,消沉,吃不好飯,盼著上班(小時候是盼著開學… )…
事實上,不僅僅是Linux核心,幾乎所有的 現代作業系統 都沒有為支援100Gb/s做好準備。
這是一個變革的年代, 現代作業系統 已經不再 現代 !
我們回望一下類似Unix/Linux,Windows NT這些作業系統是如何被稱作 現代 的。嗯,是因為虛擬記憶體系統。
是 隔離的地址空間 讓作業系統一下子進入了現代社會。在此之前,作業系統都是譚浩強書裡寫的那種一旦操作空指標就會系統崩潰的系統。
自打作業系統成為現代作業系統後,貌似它就沒有再有過突破性的進化,但是其周邊,確實翻天覆地了。
先看CPU和系統架構,先是其主頻的瘋漲,然後又是多核架構。主頻增加這個對於作業系統核心來講是好事,在單位時間內能多執行很多指令,這完全是一個打雞血的過程。然而多核心架構就讓幾乎所有的作業系統核心有點開始吃力應對了。其對資料同步的解法中,往往都是見招拆招地加鎖。
多核心架構對系統性能的作用力和主頻增加的作用力方向是相反的,如果主頻的增加讓CPU在單位時間執行了更多的指令,那麼多核之間的溝通成本抵消了這個主頻提升帶來的收益,因為同步成本是高昂的。
多核心架構重演了 人月神話 。
最後的結果就是,支援SMP多核架構的作業系統核心,其實就是給當年引入虛擬記憶體時的現代作業系統全部掛滿了枷鎖而已。單就作業系統核心本身而言,它更慢了,而不是更快了!
意思是說,多核心架構下,單獨的CPU上,作業系統的執行效率要比單核架構下作業系統的執行效率更低了!核數越多,溝通同步成本越大,最終讓效能/核心數曲線上凸!
而溝通同步的方式,無外乎就是,鎖!
所以說,鎖是阻止作業系統效能多核擴充套件性伸縮性的罪魁禍首!
事實上,Linux核心也好,UNIX也好,Windows NT也好,根本就不是為多核心架構而設計的,它們只是 簡單適應了SMP而已 。
作業系統雖然是現代的, 但是卻不是當代的! (我記得上小學和初中那會兒,老師說過現代和當代的區別 )
在現代作業系統發展停滯不前的時候,硬體卻沒有閒著。
100Gb/s網絡卡的意思是說, 如果有100Gb的資料在緩衝區裡,它可以在1秒中把它們全部發送出去 。但問題是, 作業系統有能力在1秒鐘內準備好100Gb的資料嗎?
我們知道,在我們對作業系統的傳統認知中,資料的源頭來自於使用者態緩衝區,經由作業系統核心協議棧,將資料懟到網絡卡快取區。我們可以簡單測算一下,作業系統的核心協議棧有沒有能力1秒鐘往網絡卡懟100Gbit的資料。
這裡有幾個簡單的統計資料統計點,獲取這些資料的方法:
- 在tcp_write_xmit函式的while迴圈裡打點,看看傳送一個skb需要多久;
- 使用pktgen類似的機制,測算單包傳送延時。
在如今常見的1Gb/s的網絡卡上發包測算,平均約4微秒傳送一個Full Mss的包,貌似Linux核心對於千兆網絡卡應對的還不錯,但這並不意味著它應對10Gb/s,40Gb/s,100Gb/s這些傳送速率時,是可以線性擴充套件的!
簡單反算,100Gb/s需要單包傳送延時在120納秒以內,我們只需要測算一下120納秒夠不夠核心協議棧處理一個數據包就可以了。
納秒,這是一個cache級別的時間,如果發生了一次cache命中,至少可以節省20到30納秒的時間,但是反過來如果很不幸cache missing了,那麼就要在120納秒中扣除20到30納秒,這樣就剩下90納秒了。
該重頭戲了:
- 一次spinlock需要20納秒左右的時間;
- 一次記憶體分配需要大概60納秒的時間;
很不幸,沒有時間剩下來了。以上的測算還是基於64位元組的小包,絲毫沒有包括真正的處理開銷!而我們知道,協議棧處理過程中,有超級多的協議邏輯…120納秒遠遠不夠!
在協議棧處理資料包併發送的過程中,記憶體分配和記憶體操作將會引入巨大的延時,這十有八九又會牽扯到cache missing!
從另一個角度看,Linux核心作為一個通用作業系統核心,顯然並沒有針對單獨的特性做極端的效能優化,這個意義上,我不是說它沒有為大規模支援100Gb/s網絡卡做好準備,而是它可能根本就沒有準備在支援這種高速網絡卡的競賽中取得勝利!這方面你可以和David Miller交流一下,看看在他看來,程式碼的可維護性,簡潔性,統一處理這些和極端的效能優勢相比,哪個更重要。
不過,無論如何,Linux核心,Windows NT之類的OS核心在多核心架構下無法線性擴充套件,這確實是阻礙其從 現代作業系統 進化到 當代作業系統 的路易十六!
浙江溫州皮鞋溼,下雨進水不會胖!