最近在做連續數據流的緩沖系統,C語言代碼實現後,粗略測試了下,功能上應該沒有問題。那麼,接下來就該測試性能了。輸入 top 命令,的确可以看到一系列 cpu 使用率,其中一個值得注意的子項就是 io 使用率了,如下圖:
top 命令
上圖中 io 前面的數字是什麼意思呢?是指 CPU 有 63% 的時間花費在 io 上了嗎?在 Linux 中輸入 man 命令查看相關手冊,發現 io(wait) 被解釋為“等待 I/O 完成的時間”。
“等待 I/O 完成的時間”
如果按照手冊對 iowait 字面上的解釋,是很容易陷入誤區的。因為就上例而言,似乎 CPU 有 63% 的時間消耗在等待 I/O 操作完成,導緻 CPU 的性能白白浪費這麼多。
其實不是的,Linux 是一個成熟的操作系統,它才不會讓 CPU 寶貴的性能白白浪費在耗時的 I/O 等待上,實際上,如果當前系統還有其他任務需要使用 CPU,Linux 會将等待 I/O 完成的任務暫時挂起,将 CPU 使用權暫時交給有需要的任務。
那麼 iowait 到底是什麼意思呢?有人認為,iowait 隻是 CPU 空閑(idle)時間的一個子集,也就是說 iowait 其實可以歸類到 idle 狀态,本質上表示 CPU 是空閑的,隻不過 iowait 表示任務中有等待 I/O 操作完成的時間。
iowait 到底是什麼意思呢?
這樣認為有一定的道理,畢竟哪怕 iowait 的數值是 100%,也僅僅是說明是 CPU 把時間都花在“等待”上了,這樣的情況一般隻有在當前系統沒有其他任務需要使用 CPU 時才會發生。因為一旦有其他任務需要使用 CPU,Linux 内核會立刻将 CPU 提供給該任務使用,CPU 時間就不再全部是“等待I/O”花費的了(不再是 100% io 了)。
不過讀者應該明白的是,“idle”是 CPU 的狀态,而 “iowait”則是任務的狀态。對于單核 CPU 來說,同時隻能有一個任務運行,上述說法可以認為是準确的。但是對于多核 CPU 來說,情況就有些不同了。
例如,某個系統擁有 4 個 CPU,有一個 I/O 超密集型任務正在運行,那麼,iowait 會是 100% 呢,還是 25% 呢?換句話說,iowait 會是在其中一個 CPU 上 100%,其他CPU 上 0% 呢,還是會在 4 個 CPU 上平均 25 % 呢?
簡單做一個實驗
簡單做一個實驗就可以了。我們使用 Linux 中的 dd 命令模拟高密集 I/O 任務,這一過程可以通過輸入以下命令實現:
dd if=/dev/sda of=/dev/null bs=1MB
這條命令可能需要 root 權限,/dev/sda 是我的磁盤,讀者可能需要換成自己的節點名。
此時,通過 top 命令可以查看到下面這樣的結果:
top 命令
圖中的 “wa”表示 I/O 等待時間(它和 io、iowait 是一個意思,名字不同而已)。可見,Linux 此時采用單個 CPU 處理 I/O 任務。如果讀者細心的話,應該能夠發現,I/O 任務隻是偶爾的切換到其他 CPU 上運行,這是為了保證 CPU 緩沖的命中率,Linux 内核盡量讓任務在單個 CPU 中運行。
在其他一些系統中,I/O 任務可能會在各個CPU中頻繁的切換,此時會産生下面這樣的結果:
I/O 任務可能會在各個CPU中頻繁的切換
假設 dd 命令是系統中執行 I/O 的唯一任務,那麼在同一時刻,最多隻會有一個 CPU 處理 I/O 等待任務。因此,實際上 34.8 20.9 26.7 3.7=86.1,接近但低于100。
進一步實驗為了讓實驗更可重現,我們可以使用 taskset 命令為任務指定 CPU:
taskset 1 dd if=/dev/sda of=/dev/null bs=1MB
應該注意,taskset 後的數字 1 并不是 CPU 的編号,而是一種掩碼。
此時通過 top 命令查看 CPU 使用請看,應該能夠發現 CPU0 的 wa 項接近 100,這說明 CPU0 幾乎所有的時間都花在等待 I/O 操作完成上。那麼,是不是此時 CPU 就沒有精力處理其他任務了呢?我們再輸入下面這條命令:
taskset 1 sh -c "while true; do true; done"
上面這條命令是在相同的 CPU 上執行一個死循環,用于模拟計算密集型任務,它是不是就沒有機會執行了呢?輸入 top 命令,得到如下結果:
CPU0 的 wa 降低為 0 了
CPU0 的 wa 降低為 0 了,與此同時,用戶态和系統态的 CPU 時間接近 100% 了。這是意料之中的,因為本質上 CPU 是空閑的,Linux 内核當然可以把 CPU 交給第二個任務使用。原本用于等待 I/O 完成的 CPU 時間,現在用于處理第二個任務了。此時通過 top 命令查看 wa,自然得到接近 0 的結果。
小結現在基本就清楚 top 命令中 % io 的含義了:對于指定的 CPU 來說,iowait 表示在此時間内,CPU 其實是空閑的,不過 CPU 并不是嚴格意義上的“空閑”,畢竟它還需要等待 I/O 操作完成。對于産生 I/O 操作請求的線程來說,它會阻塞等待 I/O 操作完成。理解這一點,對于我們開發I/O操作密集的C語言程序是非常有幫助的。
點個贊再走吧
歡迎在評論區一起讨論,質疑。文章都是手打原創,每天最淺顯的介紹C語言、linux等嵌入式開發,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦(最近發現有些帳号搬運我的文章并且标上原創标簽,有些可恥,請注明出處!!)。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!