
前面的幾篇文章里討論過了行程背景關系切換和系統呼叫對系統性能的影響,我們今天再來看另外一個CPU吃貨,那就是軟中斷,
你在用vmstat或者其他一些工具查看系統CPU消耗的時候,發現有兩列是單獨列出來的,分別是是hi和si,他們分別是硬中斷和軟中斷,既然vmstat把中斷的開銷單獨列出來了,就說明一個問題,中斷吃起CPU來那也是絲毫不含糊,
我們沒必要啃明白軟中斷的所有原理,但從一名追求性能的開發者的角度來看,我們有必要了解以下問題:
- 一次軟中斷的開銷到底多大?
- 你的服務器上被軟中斷吃掉了多少CPU時間?
如果你和我一樣好奇上面的問題的答案,那請跟我來!
軟中斷的誕生
CPU正常情況下都是專心處理用戶的行程的,當外部的硬體或軟體有訊息想要通知CPU,就會通過中斷請求(interrupt request,IRQ)的方式來進行,比如當你的滑鼠有了點擊產生,再比如磁盤設備完成了資料的讀取的時候,都會通過中斷通知CPU作業已完成,
但是當中斷機制應用到網路IO的時候,就產生了一點點問題,網路包收到后的處理作業,不像滑鼠、鍵盤、磁盤IO讀取完成那樣簡單,而是要進行大量的內核協議堆疊的處理,最終才能放到行程的接收快取區中,假如只用一種中斷(硬終端)的方式來處理網路IO,由于硬中斷的優先級又比較高,這樣CPU就會忙于處理大量的網路IO而不能及時回應鍵盤滑鼠等事情,導致作業系統實時性變差,你會感徑訓器以卡一卡的,
所以現代的Linux又發明了軟體中斷,配合硬中斷來處理網路IO, 硬中斷你可以理解只是個收包的,把包收取回來放到“家里”就完事,很快就能完成,這樣不耽誤CPU回應其它外部高優先級的中斷,而軟中斷優先級較低,負責將包進行各種處理,完成從驅動層、到網路協議堆疊,最終把處理出來的資料放到socker的接收buffer中,
軟中斷消耗的CPU周期相對比硬中斷要多不少,所以我們本文來重點關注軟中斷的開銷,
軟中斷開銷估算
前面大致介紹了軟中斷的來龍去脈,好了直接進入本文的主題上,軟中斷開銷到底多大,好了,請跟我來一起計算:
1) 查看軟中斷總耗時
首先用top命令可以看出每個核上軟中斷的開銷占比,是在si列
top
top - 19:51:24 up 78 days, 7:53, 2 users, load average: 1.30, 1.35, 1.35
Tasks: 923 total, 2 running, 921 sleeping, 0 stopped, 0 zombie
Cpu(s): 7.1%us, 1.4%sy, 0.0%ni, 90.1%id, 0.1%wa, 0.2%hi, 1.2%si, 0.0%st
Mem: 65872372k total, 64711668k used, 1160704k free, 339384k buffers
Swap: 0k total, 0k used, 0k free, 55542632k cached
如上圖所示,CPU大約花費了1.2%的時鐘周期在軟中斷上,也就是說每個核要花費12ms,
2)查看軟中斷次數
再用vmstat命令可以看到軟中斷的次數
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 1231716 339244 55474204 0 0 6 496 0 0 7 3 90 0 0
2 0 0 1231352 339244 55474204 0 0 0 128 57402 24593 5 2 92 0 0
2 0 0 1230988 339244 55474528 0 0 0 140 55267 24213 5 2 93 0 0
2 0 0 1230988 339244 55474528 0 0 0 332 56328 23672 5 2 93 0 0
每秒大約有56000次左右的軟中斷(該機器上是web服務,網路IO密集型的機器,其它中斷可以忽略不計),
3)計算每次軟中斷的耗時
該機器是16核的物理實機,故可以得出每個軟中斷需要的CPU時間是=12ms/(56000/16)次=3.428us
從實驗資料來看,一次軟中斷CPU開銷大約3.4us左右
軟中斷的背景關系切換
前文我們計算出了一個相對比較精確的開銷時間,這個時間里其實包含兩部分,一是背景關系切換開銷,二是軟中斷內核執行開銷, 其中背景關系切換和系統呼叫、行程背景關系切換有很多相似的地方,讓我們將他們進行一個簡單的對比:
1.和系統呼叫開銷對比
《深入理解Linux內核-第五章》開頭的一句話,很形象地把中斷和系統呼叫兩個不相關的概念聯系了起來,巧妙地找到了這二者之間的相似處,“你可以把內核看做是不斷對請求進行回應的服務器,這些請求可能來自在CPU上執行的行程,也可能來自發出中斷的外部設備,老板的請求相當于中斷,而顧客的請求相當于用戶態行程發出的系統呼叫”,
軟中斷和系統呼叫一樣,都是CPU停止掉當前用戶態背景關系,保存作業現場,然后陷入到內核態繼續作業,二者的唯一區別是系統呼叫是切換到同行程的內核態背景關系,而軟中斷是則是切換到了另外一個內核行程ksoftirqd上,
而事實上,早期的系統呼叫也還真的是通過匯編指令int(中斷)來實作的,當用戶態行程發出int $0x80指令時,CPU切換到內核態并開始執行system_call函式,后來大家覺得系統呼叫實在是太慢了,因為int指令要執行一致性和安全性檢查,后來內核又該用了Intel提供的“快速系統呼叫”的sysenter指令,才算是和中斷脫離了一點點干系,而軟中斷必須得進行這些檢查,所以從這點上來看,中斷的開銷應該是比系統呼叫的開銷要多的,
根據前文的實驗結果,系統呼叫開銷是200ns起步,沒看過這個文章的同學可以關注我,然后從歷史文章里找,
2.和行程背景關系切換開銷對比
和行程背景關系切換比較起來,行程背景關系切換是從用戶行程A切換到了用戶行程B,而軟中斷切換是從用戶行程A切換到了內核執行緒ksoftirqd上,
而ksoftirqd作為一個內核控制路徑,其處理程式比一個用戶行程要輕量,所以背景關系切換開銷相對比行程切換要稍一些,大家感興趣的,可以繼續閱讀《深入理解Linux內核》的-第五章,
根據前文的實驗結果,行程背景關系切換開銷是3us-5us,沒看過這個文章的同學可以關注我,然后從歷史文章里找,
相關Linux命令
- top: si列展示軟中斷造成CPU開銷
- vmstat 1:in列每秒展示軟中斷次數
- cat /proc/softirqs:展示所有軟中斷發生的總數,包括TIMER、NET_TX、NET_RX等

開發內功修煉之CPU篇專輯:
- 1.你以為你的多核CPU都是真核嗎?多核“假象”
- 2.聽說你只知記憶體,而不知快取?CPU表示很傷心!
- 3.TLB快取是個神馬鬼,如何查看TLB miss?
- 4.行程/執行緒切換究竟需要多少開銷?
- 5.協程究竟比執行緒牛在什么地方?
- 6.軟中斷會吃掉你多少CPU?
- 7.一次系統呼叫開銷到底有多大?
- 8.一次簡單的php請求redis會有哪些開銷?
- 9.函式呼叫太多了會有性能問題嗎?
我的公眾號是「開發內功修煉」,在這里我不是單純介紹技術理論,也不只介紹實踐經驗,而是把理論與實踐結合起來,用實踐加深對理論的理解、用理論提高你的技術實踐能力,歡迎你來關注我的公眾號,也請分享給你的好友~~~
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/198232.html
標籤:PHP
上一篇:追蹤將服務器CPU耗光的兇手
下一篇:python筆記04
