當前位置:
首頁 > 知識 > CPU說:這個世界慢!死!了!

CPU說:這個世界慢!死!了!

經常聽到有人說磁碟很慢、網路很卡,這都是站在人類的感知維度去表述的,比如拷貝一個文件到硬碟需要幾分鐘到幾十分鐘,夠我去吃個飯啦;而從網路下載一部電影,有時候需要幾個小時,我都可以睡一覺了。

最為我們熟知的關於計算機不同組件速度差異的圖表,是下面這種金字塔形式:越往上速度越快,容量越小,而價格越高。這張圖只是給了我們一個直觀地感覺,並沒有對各個速度和性能做出量化的說明和解釋。而實際上,不同層級之間的差異要比這張圖大的多。這篇文章就讓你站在 CPU 的角度看這個世界,說說到底它們有多慢。

希望你看到看完這篇文章能明白兩件事情:

磁碟和網路真的很慢

性能優化是個複雜的系統性的活

註:所有的數據都是來自這個地址。所有的數據會因為機器配置不同,或者硬體的更新而有出入,但是不影響我們直覺的感受。如果對這些數據比較感興趣,這個網址給出了不同年份一些指標的數值。

數據

先來看看 CPU 的速度,就拿我的電腦來說,主頻是 2.6G,也就是說每秒可以執行 2.6*10^9 個指令,每個指令只需要 0.38ns(現在很多個人計算機的主頻要比這個高,配置比較高的能達到 3.0G+)。我們把這個時間當做基本單位 1s,因為 1s 大概是人類能感知的最小時間單位。

一級緩存讀取時間為 0.5ns,換算成人類時間大約是 1.3s,大約一次或者兩次心跳的時間。這裡能看出緩存的重要性,因為它的速度可以趕上 CPU,程序本身的 locality 特性加上指令層級上的優化,cache 訪問的命中率很高,這最終能極大提高效率。

分支預測錯誤需要耗時 5ns,換算成人類時間大約是 13s,這個就有點久了,所以你會看到很多文章分析如何優化代碼來降低分支預測的幾率,比如這個得分非常高的 stackoverflow 問題。

二級緩存時間就比較久了,大約在 7ns,換算成人類時間大約是 18.2s,可以看到的是如果一級緩存沒有命中,然後去二級緩存讀取數據,時間差了一個數量級。

小知識:為什麼需要多層的 CPU 緩存呢?這篇文章通過一個通俗易懂的例子給出了講解。

我們繼續,互斥鎖的加鎖和解鎖時間需要 25ns,換算成人類時間大約是 65s,首次達到了一分鐘。並發編程中,我們經常聽說鎖是一個很耗時的東西,因為在微波爐里加熱一個東西需要一分鐘的話,你要在那傻傻地等蠻久了。

然後就到了內存,每次內存定址需要 100ns,換算成人類時間是 260s,也就是4分多鐘,如果讀一些不需要太多思考的文章,這麼久能讀完2-3千字(這個快閱讀的時代,很少人在手機上能靜心多這麼字了)。看起來還不算壞,不多要從內存中讀取一段數據需要的時間會更多。到了內存之後,時間就變了一個量級,CPU 和內存之間的速度瓶頸被稱為馮諾依曼瓶頸。

一次 CPU 上下文切換(系統調用)需要大約 1500ns,也就是 1.5us(這個數字參考了這篇文章,採用的是單核 CPU 線程平均時間),換算成人類時間大約是 65分鐘,嗯,也就是一個小時。我們也知道上下文切換是很耗時的行為,畢竟每次浪費一個小時,也很讓人有罪惡感的。上下文切換更恐怖的事情在於,這段時間裡 CPU 沒有做任何有用的計算,只是切換了兩個不同進程的寄存器和內存狀態;而且這個過程還破壞了緩存,讓後續的計算更加耗時。

在 1Gbps 的網路上傳輸 2K 的數據需要 20us,換算成人類時間是 14.4小時,這麼久都能把《星球大戰》六部曲看完了(甚至還加上吃飯撒尿的時間)!可以看到網路上非常少數據傳輸對於 CPU 來說,已經很漫長。而且這裡的時間還是理論最大值,實際過程還要更慢一些。

SSD 隨機讀取耗時為 150us,換算成人類時間大約是 4.5天。換句話說,SSD 讀點數據,CPU 都能休假,報團參加周邊遊了。雖然我們知道 SSD 要比機械硬碟快很多,但是這個速度對於 CPU 來說也是像烏龜一樣。I/O 設備 從硬碟開始速度開始變得漫長,這個時候我們就想起內存的好處了。盡量減少 IO 設備的讀寫,把最常用的數據放到內存中作為緩存是所有程序的通識。像 memcached 和 redis 這樣的高速緩存系統近幾年的異軍突起,就是解決了這裡的問題。

從內存中讀取 1MB 的連續數據,耗時大約為 250us,換算成人類時間是 7.5天,這次假期升級到國慶七天國外遊了。

同一個數據中心網路上跑一個來回需要 0.5ms,換算成人類時間大約是 15天,也就是半個月的時間。如果你的程序有段代碼需要和數據中心的其他伺服器交互,在這段時間裡 CPU 都已經狂做了半個月的運算。減少不同服務組件的網路請求,是性能優化的一大課題。

從 SSD 讀取 1MB 的順序數據,大約需要 1ms,換算成人類時間是 1個月。也就是說 SSD 讀一個普通的文件,如果要等你做完,CPU 一個月時間就荒廢了。儘管如此,SSD 已經很快啦,不信你看下面機械磁碟的表現。

磁碟定址時間為 10ms,換算成人類時間是 10個月,剛好夠人類創造一個新的生命了。如果 CPU 需要讓磁碟泡杯咖啡,在它眼裡,磁碟去生了個孩子,回來告訴它你讓我泡的咖啡好了。機械硬碟使用 RPM(Revolutions Per Minute/每分鐘轉速) 來評估磁碟的性能:RPM 越大,平均定址時間更短,磁碟性能越好。定址只是把磁頭移動到正確的磁軌上,然後才能讀取指定扇區的內容。換句話說,定址雖然很浪費時間,但其實它並沒有辦任何的正事(讀取磁碟內容)。

從磁碟讀取 1MB 連續數據需要 20ms,換算成人類時間是 20個月。IO 設備是計算機系統的瓶頸,希望讀到這裡你能更深切地理解這句話!如果還不理解,不妨想想你在網上買的東西,快遞送了將近兩年,你的心情是怎麼樣的。

從世界上不同城市網路上走一個來回,平均需要 150ms(參考世界各地 ping 報文的時間),換算成人類時間是 12.5年。不難理解,所有的程序和架構都會盡量避免不同城市甚至是跨國家的網路訪問,CDN 就是這個問題的一個解決方案:讓用戶和最接近自己的伺服器交互,從而減少網路上報文的傳輸時間。

虛擬機重啟一次大約要 4s 時間,換算成人類的時間是 3百多年。對於此,我想到了喬布斯要死命優化 Mac 系統開機啟動時間的故事。如果機器能少重啟而且每次啟動能快一點,不僅能救人命,也能救 CPU 的命。

物理伺服器重啟一次需要 5min,換算成人類時間是 2萬5千年,快趕上人類的文明史了。5 分鐘人類都要等一會了,更別提 CPU 了,所以沒事不要亂重啟伺服器啊,分分鐘終結一個文明的節奏。


參考資料

What Every Programmer Should Know About Memory

Getting Physical With Memory


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員之家 的精彩文章:

趣圖:感動到哭的程序員
身為程序員,你是怎麼跟非程序員解釋編程的?

TAG:程序員之家 |