日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

聊聊 top 命令中的 CPU 使用率

發布時間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 聊聊 top 命令中的 CPU 使用率 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前寫過cpu占用率的文章

CPU占用率是什么?

====

平常我們使用?top?命令來查看系統的性能情況,在?top?命令中可以看到很多不同類型的 CPU 使用率,如下圖紅框中標出部分:

下面,我們來介紹一下這些 CPU 使用率的意義:

  • us:user time,表示 CPU 執行用戶進程的時間,包括 nice 時間。通常都是希望用戶空間CPU越高越好。

  • sy:system time,表示 CPU 在內核運行的時間,包括 IRQ 和 softirq。系統 CPU 占用越高,表明系統某部分存在瓶頸。通常這個值越低越好。

  • ni:nice time,具有優先級的用戶進程執行時占用的 CPU 利用率百分比。

  • id:idle time,表示系統處于空閑期,等待進程運行。

  • wa:waiting time,表示 CPU 在等待 IO 操作完成所花費的時間。系統不應該花費大量的時間來等待 IO 操作,否則就說明 IO 存在瓶頸。

  • hi:hard IRQ time,表示系統處理硬中斷所花費的時間。

  • si:soft IRQ time,表示系統處理軟中斷所花費的時間。

  • st:steal time,被強制等待(involuntary wait)虛擬 CPU 的時間,此時 Hypervisor 在為另一個虛擬處理器服務。

當然,單靠上面的解釋來理解它們的意義還是比較困難的。所以,本文主要從源碼的角度來分析它們到底代表什么。


時鐘中斷

首先,我們要知道統計 CPU 使用情況在什么地方執行的。在分析之前,我們先來了解下?時鐘中斷:

時鐘中斷:是一種硬中斷,由時間硬件(系統定時器,一種可編程硬件)產生。當 CPU 接收到時鐘中斷信號后,會在處理完當前指令后調用?時鐘中斷處理程序?來完成更新系統時間、執行周期性任務等。

可以發現,統計 CPU 使用情況是在?時鐘中斷處理程序?中完成的。

每個 CPU 的使用情況通過?cpu_usage_stat?結構來記錄,我們來看看其定義:

struct?cpu_usage_stat?{cputime64_t?user;cputime64_t?nice;cputime64_t?system;cputime64_t?softirq;cputime64_t?irq;cputime64_t?idle;cputime64_t?iowait;cputime64_t?steal;cputime64_t?guest; };

從?cpu_usage_stat?結構的定義可以看出,其每個字段與?top?命令的 CPU 使用率類型一一對應。在內核初始化時,會為每個 CPU 創建一個?cpu_usage_stat?結構,用于統計 CPU 的使用情況。

OK,現在我們來分析下內核是怎么統計 CPU 的使用情況的。

每次執行?時鐘中斷處理程序?都會調用?account_process_tick?函數進行 CPU 使用情況統計,我們來分析一下?account_process_tick?函數的實現:

void?account_process_tick(struct?task_struct?*p,?int?user_tick) {cputime_t?one_jiffy_scaled?=?cputime_to_scaled(cputime_one_jiffy);struct?rq?*rq?=?this_rq();//?說明:user_tick 變量標識當前是否處于執行用戶應用程序if?(user_tick)?{//?1.?如果?CPU?在執行用戶程序,?那么調用?account_user_time?進行統計account_user_time(p,?cputime_one_jiffy,?one_jiffy_scaled);}?else?if?((p?!=?rq->idle)?||?(irq_count()?!=?HARDIRQ_OFFSET))?{//?2.?如果?CPU?在執行內核代碼,?那么調用?account_system_time?進行統計account_system_time(p,?HARDIRQ_OFFSET,?cputime_one_jiffy,one_jiffy_scaled);}?else?{//?3.?否則說明?CPU?在執行?idle?進程(也就是處于空閑狀態),?那么調用?account_idle_time?進行統計account_idle_time(cputime_one_jiffy);} }

account_process_tick?函數主要分 3 種情況進行統計,如下:

  • 如果 CPU 在執行用戶程序,那么調用?account_user_time?進行統計。

  • 如果 CPU 在執行內核代碼,那么調用?account_system_time?進行統計。

  • 否則說明 CPU 在執行 idle 進程(也就是處于空閑狀態),那么調用?account_idle_time?進行統計。

CPU 使用情況統計

下面我們分別對這 3 種統計進行分析。

1. 統計用戶程序執行時間

統計用戶程序的執行時間是通過?account_user_time?函數來完成的,我們來看看其實現:

void?account_user_time(struct?task_struct?*p,?cputime_t?cputime,cputime_t?cputime_scaled) {//?獲取?CPU?的統計結構(每個CPU一個?cpu_usage_stat?結構)struct?cpu_usage_stat?*cpustat?=?&kstat_this_cpu.cpustat;?cputime64_t?tmp;...//?分?2?種情況統計?CPU?的使用情況//?1.?如果進程的?nice?值大于0,?那么將會統計到?nice?字段中//?2.?如果進程的?nice?值小于等于0,?那么將會統計到?user?字段中if?(TASK_NICE(p)?>?0)cpustat->nice?=?cputime64_add(cpustat->nice,?tmp);elsecpustat->user?=?cputime64_add(cpustat->user,?tmp);... }

account_user_time?函數主要分兩種情況統計:

  • 如果進程的?nice?值大于0,那么將會增加到 CPU 統計結構的?nice?字段中。

  • 如果進程的?nice?值小于等于0,那么增加到 CPU 統計結構的?user?字段中。

這里說明一下進程?nice?值的作用,nice?值越大,說明進程的優先級越低。所以,nice?統計值主要用來統計低優先級進程的占使用 CPU 的情況。也說明了,user?和?nice?統計值都屬于執行用戶程序的 CPU 時間。

2. 統計內核代碼執行時間

如果在發生時鐘中斷前,CPU 處于內核態,也就是說在執行內核代碼。那么將會調用?account_system_time?函數進行統計,account_system_time?函數實現如下:

void?account_system_time(struct?task_struct?*p,?int?hardirq_offset,cputime_t?cputime,?cputime_t?cputime_scaled) {//?獲取?CPU?的統計結構(每個CPU一個?cpu_usage_stat?結構)struct?cpu_usage_stat?*cpustat?=?&kstat_this_cpu.cpustat;cputime64_t?tmp;...//?主要分?3?種情況進行統計//?1.?如果當前處于硬中斷執行上下文,?那么統計到?irq?字段中//?2.?如果當前處于軟中斷執行上下文,?那么統計到?softirq?字段中//?3.?否則統計到?system?字段中if?(hardirq_count()?-?hardirq_offset)cpustat->irq?=?cputime64_add(cpustat->irq,?tmp);else?if?(softirq_count())cpustat->softirq?=?cputime64_add(cpustat->softirq,?tmp);elsecpustat->system?=?cputime64_add(cpustat->system,?tmp);... }

account_system_time?函數主要分 3 種情況進行統計:

  • 如果當前處于硬中斷執行上下文,那么增加到 CPU 統計結構的?irq?字段中。

  • 如果當前處于軟中斷執行上下文,那么增加到 CPU 統計結構的?softirq?字段中。

  • 否則增加到 CPU 統計結構的?system?字段中。

從上面代碼可以看出,irq?和?softirq?統計值也算是內核代碼執行時間。

3. idle 進程執行時間統計

當系統中沒有可運行的進程時,將會執行?idle?進程。也就是說,當系統執行?idle?進程時,表示系統正處于空閑狀態。

idle?進程執行時間統計由?account_idle_time?函數完成,其實現如下:

void?account_idle_time(cputime_t?cputime) {struct?cpu_usage_stat?*cpustat?=?&kstat_this_cpu.cpustat;cputime64_t?cputime64?=?cputime_to_cputime64(cputime);struct?rq?*rq?=?this_rq();//?分?2?種情況統計?CPU?的使用情況//?1.?如果系統有進程正在等待?I/O?操作完成,?那么將統計到?iowait?字段中//?2.?否則將統計到?idle?字段中if?(atomic_read(&rq->nr_iowait)?>?0)cpustat->iowait?=?cputime64_add(cpustat->iowait,?cputime64);elsecpustat->idle?=?cputime64_add(cpustat->idle,?cputime64); }

account_idle_time?函數也分兩種情況進行統計:

  • 如果系統中有正在等待 I/O 操作完成的進程,那么增加到 CPU 統計結構的?iowait?字段中。

  • 否則增加到 CPU 統計結構的?idle?字段中。

從上面的分析可以看出,iowait?統計值也屬于空閑時間的一種。

top 命令的 CPU 使用率

通過源碼分析,我們知道?top?命令中 CPU 使用率各種類型的意思,現在我們來介紹一下?top?命令是怎么計算各種類型的 CPU 使用率。

要獲取各個 CPU 的使用情況信息,可以通過讀取?/proc/stat?文件獲取,如下:

[vagrant@localhost?~]$?cat?/proc/stat cpu??245?10?1142?1097923?95?0?28?0?0?0 cpu0?245?10?1142?1097923?95?0?28?0?0?0 ...

上面的結果顯示了 CPU 的使用情況信息,第一行代表所有 CPU 的總和,而第二行開始表示每個 CPU 核心的使用情況信息。因為我的電腦只有一個核,所以只有一條數據。

下面說說這些數據的意義,從第一個數值開始分別代表:user?,nice,system,idle,iowait,?irq,softirq,steal。

所以,top?命令的 CPU 使用率計算公式如下:

CPU總時間 = user + nice + system + idle + wait + irq + softirq + steal %us = user / CPU總時間 %ni = nice / CPU總時間 %sy = system / CPU總時間 %id = idel / CPU總時間 %wa = wait / CPU總時間 %hi = irq / CPU總時間 %si = softirq / CPU總時間 %st = steal / CPU總時間

嗯,看起來還是挺簡單的。

總結

本文主要分析了?top?命令中的 CPU 使用率的意義和實現原理,希望通過本文,能夠幫助大家對?top?命令有更深的認識。


推薦閱讀:

專輯|Linux文章匯總

專輯|程序人生

專輯|C語言

我的知識小密圈

關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。

歡迎點贊,關注,轉發,在看,您的每一次鼓勵,我都將銘記于心~

嵌入式Linux

微信掃描二維碼,關注我的公眾號

總結

以上是生活随笔為你收集整理的聊聊 top 命令中的 CPU 使用率的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。