国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

CPU性能優(yōu)化——“瑞士軍刀“

這篇具有很好參考價(jià)值的文章主要介紹了CPU性能優(yōu)化——“瑞士軍刀“。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

CPU性能優(yōu)化——“瑞士軍刀“,性能優(yōu)化,性能優(yōu)化

背景

????????最近在做一些工具的預(yù)研工作,會(huì)涉及到對(duì)工具的壓力測(cè)試,分析工具的資源消耗等問(wèn)題,其中CPU 資源消耗是關(guān)鍵指標(biāo)之一。為了后續(xù)性能優(yōu)化做準(zhǔn)備,回顧了以前相關(guān)CPU優(yōu)化知識(shí),并做總結(jié)分享。希望能幫助到正在遇到相關(guān)問(wèn)題的同事。

CPU 使用率

????????cpu 使用率,是我們做嵌入式開(kāi)發(fā)者,經(jīng)常會(huì)遇到的一個(gè)性能指標(biāo)。但是每個(gè)人對(duì)他的理解可能有點(diǎn)不一樣。在這里按照我個(gè)人的理解,和大家簡(jiǎn)單介紹一下。

何為CPU 使用率

????????使用率:通常是指在一定時(shí)間內(nèi)實(shí)際使用的資源或服務(wù)與可使用的資源或服務(wù)之間的比率。

????????CPU 使用率:?就是指一定時(shí)間內(nèi),CPU實(shí)際被占用的比例。那么核心問(wèn)題來(lái)了, CPU 被占用之后,主要用來(lái)做什么了呢

????????只有知道了CPU被用來(lái)做什么了,我們才有目標(biāo),有針對(duì)性的去優(yōu)化。

CPU 消耗在哪里?

????????我們知道CPU的核心功能就是執(zhí)行指令和處理數(shù)據(jù)。

????????從linux 系統(tǒng)中,代碼的分類(lèi),我們可以分為執(zhí)行用戶(hù)態(tài)代碼,執(zhí)行內(nèi)核態(tài)代碼,執(zhí)行中斷程序代碼

? ? ? ? 另外,linux 是多任務(wù)操作系統(tǒng),它支持遠(yuǎn)大于CPU數(shù)量的任務(wù)同時(shí)運(yùn)行。當(dāng)然這些任務(wù)不是真的同時(shí)運(yùn)行,而是系統(tǒng)在很小的時(shí)間段內(nèi),將CPU 不斷分配給任務(wù),導(dǎo)致同時(shí)運(yùn)行的錯(cuò)覺(jué)。每個(gè)任務(wù)運(yùn)行前,CPU 需要知道從哪里加載,以及從哪里運(yùn)行。也就是說(shuō)操作系統(tǒng)需要需要提前設(shè)置好任務(wù)的CPU寄存器和程序計(jì)數(shù)器(PC)。這也是CPU的上下文。同理,任務(wù)的上下文切換,根據(jù)不同的場(chǎng)景,上下文切換的資源消耗也是不一樣的。

  • 進(jìn)程上下文切換:包括了虛擬內(nèi)存、棧、全局變量等用戶(hù)空間的資源,還包括了內(nèi)核堆棧、寄存器等內(nèi)核空間的狀態(tài)的資源備份和恢復(fù)。
  • 線程上下文切換(前后線程是同一個(gè)進(jìn)程):需要對(duì)線程的私有數(shù)據(jù)進(jìn)行保存,比如線程寄存器,線程棧等。
  • 中斷上下文切換:只包括中斷服務(wù)程序的所必需的狀態(tài),包括 CPU 寄存器、內(nèi)核堆棧、硬件中斷參數(shù)等。

????????還有一種特殊的場(chǎng)景,那就是進(jìn)程占用CPU,但是卻不做任何事。那就是不可中斷狀態(tài)。

????????不可中斷狀態(tài)的進(jìn)程則是正處于內(nèi)核態(tài)關(guān)鍵流程中的進(jìn)程,并且這些流程是不可打斷的,比如最常見(jiàn)的是等待硬件設(shè)備的 I/O 響應(yīng),當(dāng)一個(gè)進(jìn)程向磁盤(pán)讀寫(xiě)數(shù)據(jù)時(shí),為了保證數(shù)據(jù)的一致性,在得到磁盤(pán)回復(fù)前,它是不能被其他進(jìn)程或者中斷打斷的,這個(gè)時(shí)候的進(jìn)程就處于不可中斷狀態(tài)。如果此時(shí)的進(jìn)程被打斷了,就容易出現(xiàn)磁盤(pán)數(shù)據(jù)與進(jìn)程數(shù)據(jù)不一致的問(wèn)題。

綜上所述, CPU 資源主要消耗在以下場(chǎng)景。

  • 執(zhí)行用戶(hù)態(tài)代碼。也就是我們寫(xiě)的應(yīng)用程序。
  • 執(zhí)行內(nèi)核態(tài)代碼。內(nèi)核驅(qū)動(dòng),系統(tǒng)調(diào)用。
  • 執(zhí)行中斷代碼。硬件中斷代碼。
  • 任務(wù)上下文切換。為了多任務(wù)正常執(zhí)行,不同任務(wù)之間切換,需要保存和加載必要的上下文。
  • 不可中斷狀態(tài)。為了避免關(guān)鍵步驟被打斷,程序占用CPU,直到關(guān)鍵步驟完成。

CPU性能分析工具

????????砍柴不誤磨刀功。分析CPU性能問(wèn)題時(shí),可以利用一些工具,大大提高我們的效率。本節(jié)介紹幾個(gè)好用的命令,其中可能有大家平時(shí)用到過(guò),但是對(duì)于其參數(shù)也許并沒(méi)有深入了解。

top

? ? ? ? top命令是我們?cè)诜治鲂阅軉?wèn)題時(shí),常用到的一個(gè)工具。執(zhí)行top -d 1?,-d 參數(shù)表示更新頻率。默認(rèn)3s。

yihua@ubuntu:~$ top -d 1
top - 23:36:05 up 22:14, ?4 users, ?load average: 0.48, 0.10, 0.03
Tasks: 330 total, ??1 running, 253 sleeping, ??0 stopped, ??0 zombie
%Cpu(s): ?9.9 us, 66.5 sy, ?0.0 ni, 23.6 id, ?0.0 wa, ?0.0 hi, ?0.0 si, ?0.0 st
KiB Mem : ?4013240 total, ?1004708 free, ?1293040 used, ?1715492 buff/cache
KiB Swap: ?2097148 total, ?2097148 free, ???????0 used. ?2398648 avail Mem
?Unknown command - try 'h' for help
???PID USER ?????PR ?NI ???VIRT ???RES ???SHR S ?%CPU %MEM ????TIME+ COMMAND
?10612 yihua ????20 ??0 ?120024 ??7940 ??6636 S 305.0 ?0.2 ??0:21.79 sysbench
?10623 yihua ????20 ??0 ??44380 ??4132 ??3328 R ??1.0 ?0.1 ??0:00.03 top
?????1 root ?????20 ??0 ?225544 ??9332 ??6636 S ??0.0 ?0.2 ??0:03.29 systemd
?????2 root ?????20 ??0 ??????0 ?????0 ?????0 S ??0.0 ?0.0 ??0:00.04 kthreadd
?????4 root ??????0 -20 ??????0 ?????0 ?????0 I ??0.0 ?0.0 ??0:00.00 kworker/0:0H
?????6 root ??????0 -20 ??????0 ?????0 ?????0 I ??0.0 ?0.0 ??0:00.00 mm_percpu_wq
?????7 root ?????20 ??0 ??????0 ?????0 ?????0 S ??0.0 ?0.0 ??0:00.09 ksoftirqd/0
?????8 root ?????20 ??0 ??????0 ?????0 ?????0 I ??0.0 ?0.0 ??0:00.61 rcu_sched
?????9 root ?????20 ??0 ??????0 ?????0 ?????0 I ??0.0 ?0.0 ??0:00.00 rcu_bh
????10 root ?????rt ??0 ??????0 ?????0 ?????0 S ??0.0 ?0.0 ??0:00.00 migration/0
????11 root ?????rt ??0 ??????0 ?????0 ?????0 S ??0.0 ?0.0 ??0:00.09 watchdog/0

其中第一行:top - 23:36:05 up 22:14, ?4 users, ?load average: 0.48, 0.10, 0.03

23:36:05 up 22:14, ?4 users?當(dāng)前系統(tǒng)時(shí)間,系統(tǒng)運(yùn)行時(shí)間,4個(gè)用戶(hù)登錄。

?load average: 0.48, 0.10, 0.03?系統(tǒng)1分鐘,5分鐘,15分鐘的負(fù)載。通過(guò)該參數(shù),可以判斷當(dāng)前系統(tǒng)整體資源運(yùn)行狀態(tài)。

第二行:Tasks: 330 total, ??1 running, 253 sleeping, ??0 stopped, ??0 zombie

當(dāng)前系統(tǒng)中共有330個(gè)任務(wù),1個(gè)正在運(yùn)行;253個(gè)處于休眠;0個(gè)處于停止,但是資源未回收;0個(gè)僵尸進(jìn)程。

第三行:%Cpu(s): ?9.9 us, 66.5 sy, ?0.0 ni, 23.6 id, ?0.0 wa, ?0.0 hi, ?0.0 si, ?0.0 st

表示當(dāng)前CPU的資源消耗狀態(tài)。參數(shù)詳情可參考以下。

user(通常縮寫(xiě)為 us),代表用戶(hù)態(tài) CPU 時(shí)間。注意,它不包括下面的 nice 時(shí)間,但包括了 guest 時(shí)間。即執(zhí)行用戶(hù)態(tài)代碼。

nice(通??s寫(xiě)為 ni),代表低優(yōu)先級(jí)用戶(hù)態(tài) CPU 時(shí)間,也就是進(jìn)程的 nice 值被調(diào)整為 1-19 之間時(shí)的 CPU 時(shí)間。這里注意,nice 可取值范圍是 -20 到 19,數(shù)值越大,優(yōu)先級(jí)反而越低。執(zhí)行用戶(hù)態(tài)代碼。

system(通常縮寫(xiě)為 sys),代表內(nèi)核態(tài) CPU 時(shí)間。執(zhí)行內(nèi)核態(tài)代碼

idle(通??s寫(xiě)為 id),代表空閑時(shí)間。注意,它不包括等待 I/O 的時(shí)間(iowait)。

iowait(通常縮寫(xiě)為 wa),代表等待 I/O 的 CPU 時(shí)間。進(jìn)程不可中斷狀態(tài)持續(xù)時(shí)間。

irq(通??s寫(xiě)為 hi),代表處理硬中斷的 CPU 時(shí)間。執(zhí)行硬中斷代碼。

softirq(通常縮寫(xiě)為 si),代表處理軟中斷的 CPU 時(shí)間。執(zhí)行軟中斷代碼。

steal(通常縮寫(xiě)為 st),代表當(dāng)系統(tǒng)運(yùn)行在虛擬機(jī)中的時(shí)候,被其他虛擬機(jī)占用的 CPU 時(shí)間。

可知當(dāng)前CPU資源主要消耗在內(nèi)核態(tài)。

通過(guò)top 命令,我們可以知道關(guān)于CPU資源的以下信息。

  1. 當(dāng)前系統(tǒng)的負(fù)載情況。
  2. 系統(tǒng)CPU資源的消耗情況。主要被消耗在哪里。
  3. 若運(yùn)氣好,還可以定位到消耗CPU資源的進(jìn)程。

vmstat

????????vmstat 是一個(gè)常用的系統(tǒng)性能分析工具,主要用來(lái)分析系統(tǒng)的內(nèi)存使用情況,也常用來(lái)分析 CPU 上下文切換和中斷的次數(shù)。

# 每隔5秒輸出1組數(shù)據(jù)
yihua@ubuntu:~$ vmstat 5
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 985808 246852 1477912 ???0 ???0 ????4 ????3 ???1 ?123 ?0 ?0 100 ?0 ?0

特別關(guān)注的四列內(nèi)容:

cs(context switch)是每秒上下文切換的次數(shù)。

in(interrupt)則是每秒中斷的次數(shù)。

r(Running or Runnable)是就緒隊(duì)列的長(zhǎng)度,也就是正在運(yùn)行和等待 CPU 的進(jìn)程數(shù)。

b(Blocked)則是處于不可中斷睡眠狀態(tài)的進(jìn)程數(shù)。

????????這個(gè)例子中的上下文切換次數(shù) cs 是 123 次,而系統(tǒng)中斷次數(shù) in 則是 1 次,而就緒隊(duì)列長(zhǎng)度 r 為1 ,不可中斷狀態(tài)進(jìn)程數(shù) b 都是 0。

通過(guò)vmstat 命令,我們可以在指定時(shí)間段內(nèi),得到以下信息。

  1. 系統(tǒng)上下文切換次數(shù)
  2. 系統(tǒng)中斷次數(shù)。包括時(shí)鐘中斷

pidstat

????????pidstat 是一個(gè)常用的進(jìn)程性能分析工具,用來(lái)實(shí)時(shí)查看進(jìn)程的 CPU、內(nèi)存、I/O 以及上下文切換等性能指標(biāo)。常用以下場(chǎng)景。

? ? ? ? 1. 查看所有進(jìn)程CPU資源消耗,確認(rèn)是哪一個(gè)進(jìn)程導(dǎo)致的CPU性能問(wèn)題

# 間隔5秒后輸出一組數(shù)據(jù)
yihua@ubuntu:~$ pidstat -u 5 1
Linux 4.15.0-213-generic (ubuntu) ??????10/24/2023 ?????_x86_64_ ???????(4 CPU)

12:15:29 AM ??UID ??????PID ???%usr %system ?%guest ??%wait ???%CPU ??CPU ?Command
12:15:35 AM ????0 ??????585 ???0.20 ???0.00 ???0.00 ???0.00 ???0.20 ????0 ?vmtoolsd
12:15:35 AM ????0 ??????879 ???0.20 ???0.00 ???0.00 ???0.00 ???0.20 ????1 ?snapd
12:15:35 AM ????0 ?????5480 ???0.00 ???0.20 ???0.00 ???0.00 ???0.20 ????2 ?kworker/2:1
12:15:35 AM ?1000 ????11892 ??42.83 ?100.00 ???0.00 ???0.00 ?100.00 ????1 ?sysbench

Average: ?????UID ??????PID ???%usr %system ?%guest ??%wait ???%CPU ??CPU ?Command
Average: ???????0 ??????585 ???0.20 ???0.00 ???0.00 ???0.00 ???0.20 ????- ?vmtoolsd
Average: ???????0 ??????879 ???0.20 ???0.00 ???0.00 ???0.00 ???0.20 ????- ?snapd
Average: ???????0 ?????5480 ???0.00 ???0.20 ???0.00 ???0.00 ???0.20 ????- ?kworker/2:1
Average: ????1000 ????11892 ??42.83 ?100.00 ???0.00 ???0.00 ?100.00 ????- ?sysbench

????????以上信息可得知,主要是sysbench?這個(gè)進(jìn)程占用了資源,且主要消耗在內(nèi)核態(tài)。該指令可以配合top 使用,若已明確系統(tǒng)CPU資源受限,可通過(guò)該命令確認(rèn)是哪一個(gè)進(jìn)程以及主要消耗在哪里。

? ? ? ? 2. 查看上下文切換的消耗,確認(rèn)是哪一個(gè)進(jìn)程或線程導(dǎo)致的CPU 問(wèn)題

yihua@ubuntu:~$ pidstat -wt 5 1
Linux 4.15.0-213-generic (ubuntu)       10/24/2023      _x86_64_        (4 CPU)

12:24:55 AM   UID      TGID       TID   cswch/s nvcswch/s  Command
12:25:00 AM     0         7         -      0.78      0.00  ksoftirqd/0
12:25:00 AM     0         -         7      0.78      0.00  |__ksoftirqd/0
12:25:00 AM     0         8         -      6.64      0.00  rcu_sched
12:25:00 AM     0         -         8      6.64      0.00  |__rcu_sched
12:25:00 AM     0        11         -      0.20      0.00  watchdog/0
12:25:00 AM     0         -        11      0.20      0.00  |__watchdog/0
12:25:00 AM     0        14         -      0.20      0.00  watchdog/1
12:25:00 AM     0         -        14      0.20      0.00  |__watchdog/1
12:25:00 AM     0        20         -      0.20      0.00  watchdog/2
12:25:00 AM     0         -        20      0.20      0.00  |__watchdog/2
12:25:00 AM     0        22         -      0.20      0.00  ksoftirqd/2
12:25:00 AM     0         -        22      0.20      0.00  |__ksoftirqd/2
12:25:00 AM     0        26         -      0.20      0.00  watchdog/3
12:25:00 AM     0         -        26      0.20      0.00  |__watchdog/3
12:25:00 AM     0        28         -      1.17      0.00  ksoftirqd/3
12:25:00 AM     0         -        28      1.17      0.00  |__ksoftirqd/3
12:25:00 AM     0       287         -      0.20      0.00  kworker/2:1H
12:25:00 AM     0         -       287      0.20      0.00  |__kworker/2:1H
12:25:00 AM     0       306         -      0.20      0.00  kworker/3:1H
12:25:00 AM     0         -       306      0.20      0.00  |__kworker/3:1H
12:25:00 AM     0       585         -     12.11      0.00  vmtoolsd
12:25:00 AM     0         -       585     12.11      0.00  |__vmtoolsd
12:25:00 AM     0         -       586      0.98      0.00  |__HangDetector
12:25:00 AM     0         -       877      0.39      0.00  |__gmain
12:25:00 AM     0         -       891      0.39      0.00  |__gmain
12:25:00 AM     0       900         -      0.20      0.00  irqbalance
12:25:00 AM     0         -       900      0.20      0.00  |__irqbalance
12:25:00 AM     0       902         -      0.20      0.00  wpa_supplicant
12:25:00 AM     0         -       902      0.20      0.00  |__wpa_supplicant
12:25:00 AM     0         -      1037      1.17      0.00  |__containerd
12:25:00 AM     0         -      1096      0.78      0.00  |__containerd
12:25:00 AM     0         -      3497      0.78      0.20  |__containerd
12:25:00 AM   121      1258         -      0.20      0.00  gnome-shell
12:25:00 AM   121         -      1258      0.20      0.00  |__gnome-shell
12:25:00 AM   121      1773         -      0.98      0.00  gsd-color
12:25:00 AM   121         -      1773      0.98      0.00  |__gsd-color
12:25:00 AM  1000      1957         -      0.20      0.00  Xorg
12:25:00 AM  1000         -      1957      0.20      0.00  |__Xorg
12:25:00 AM  1000      2104         -      0.78      0.59  gnome-shell
12:25:00 AM  1000         -      2104      0.78      0.59  |__gnome-shell
12:25:00 AM  1000         -      2110      1.37      0.00  |__llvmpipe-0
12:25:00 AM  1000         -      2111      1.56      0.00  |__llvmpipe-1
12:25:00 AM  1000         -      2112      1.76      0.00  |__llvmpipe-2
12:25:00 AM  1000         -      2113      1.37      0.00  |__llvmpipe-3
12:25:00 AM  1000      2268         -      0.98      0.00  gsd-color
12:25:00 AM  1000         -      2268      0.98      0.00  |__gsd-color
12:25:00 AM  1000      2335         -     10.16      0.00  vmtoolsd
12:25:00 AM  1000         -      2335     10.16      0.00  |__vmtoolsd
12:25:00 AM  1000         -      2729      0.20      0.00  |__gmain
12:25:00 AM  1000         -      2727      0.20      0.00  |__gmain
12:25:00 AM     0      5480         -      1.37      0.00  kworker/2:1
12:25:00 AM     0         -      5480      1.37      0.00  |__kworker/2:1
12:25:00 AM     0      9193         -      0.98      0.00  kworker/1:0
12:25:00 AM     0         -      9193      0.98      0.00  |__kworker/1:0
12:25:00 AM     0      9224         -      1.17      0.00  kworker/3:0
12:25:00 AM     0         -      9224      1.17      0.00  |__kworker/3:0
12:25:00 AM     0     10778         -      7.62      0.00  kworker/u256:0
12:25:00 AM     0         -     10778      7.62      0.00  |__kworker/u256:0
12:25:00 AM     0     11010         -      0.98      0.00  kworker/0:4
12:25:00 AM     0         -     11010      0.98      0.00  |__kworker/0:4
12:25:00 AM     0     11946         -      1.95      0.00  kworker/u256:3
12:25:00 AM     0         -     11946      1.95      0.00  |__kworker/u256:3
12:25:00 AM  1000         -     11952  21298.44 184419.14  |__sysbench
12:25:00 AM  1000         -     11953  19585.35 192591.21  |__sysbench
12:25:00 AM  1000         -     11954  20186.52 173420.90  |__sysbench
12:25:00 AM  1000         -     11955  20158.59 193855.27  |__sysbench
12:25:00 AM  1000         -     11956  19719.34 178251.37  |__sysbench
12:25:00 AM  1000         -     11957  20934.38 162003.52  |__sysbench
12:25:00 AM  1000         -     11958  22238.48 162588.67  |__sysbench
12:25:00 AM  1000         -     11959  19943.55 181168.75  |__sysbench
12:25:00 AM  1000         -     11960  20675.00 177943.16  |__sysbench
12:25:00 AM  1000         -     11961  20960.35 183560.94  |__sysbench
12:25:00 AM  1000     11962         -      0.20    229.10  pidstat
12:25:00 AM  1000         -     11962      0.20    229.49  |__pidstat

Average:      UID      TGID       TID   cswch/s nvcswch/s  Command
Average:        0         7         -      0.78      0.00  ksoftirqd/0
Average:        0         -         7      0.78      0.00  |__ksoftirqd/0
Average:        0         8         -      6.64      0.00  rcu_sched
Average:        0         -         8      6.64      0.00  |__rcu_sched
Average:        0        11         -      0.20      0.00  watchdog/0
Average:        0         -        11      0.20      0.00  |__watchdog/0
Average:        0        14         -      0.20      0.00  watchdog/1
Average:        0         -        14      0.20      0.00  |__watchdog/1
Average:        0        20         -      0.20      0.00  watchdog/2
Average:        0         -        20      0.20      0.00  |__watchdog/2
Average:        0        22         -      0.20      0.00  ksoftirqd/2
Average:        0         -        22      0.20      0.00  |__ksoftirqd/2
Average:        0        26         -      0.20      0.00  watchdog/3
Average:        0         -        26      0.20      0.00  |__watchdog/3
Average:        0        28         -      1.17      0.00  ksoftirqd/3
Average:        0         -        28      1.17      0.00  |__ksoftirqd/3
Average:        0       287         -      0.20      0.00  kworker/2:1H
Average:        0         -       287      0.20      0.00  |__kworker/2:1H
Average:        0       306         -      0.20      0.00  kworker/3:1H
Average:        0         -       306      0.20      0.00  |__kworker/3:1H
Average:        0       585         -     12.11      0.00  vmtoolsd
Average:        0         -       585     12.11      0.00  |__vmtoolsd
Average:        0         -       586      0.98      0.00  |__HangDetector
Average:        0         -       877      0.39      0.00  |__gmain
Average:        0         -       891      0.39      0.00  |__gmain
Average:        0       900         -      0.20      0.00  irqbalance
Average:        0         -       900      0.20      0.00  |__irqbalance
Average:        0       902         -      0.20      0.00  wpa_supplicant
Average:        0         -       902      0.20      0.00  |__wpa_supplicant
Average:        0         -      1037      1.17      0.00  |__containerd
Average:        0         -      1096      0.78      0.00  |__containerd
Average:        0         -      3497      0.78      0.20  |__containerd
Average:      121      1258         -      0.20      0.00  gnome-shell
Average:      121         -      1258      0.20      0.00  |__gnome-shell
Average:      121      1773         -      0.98      0.00  gsd-color
Average:      121         -      1773      0.98      0.00  |__gsd-color
Average:     1000      1957         -      0.20      0.00  Xorg
Average:     1000         -      1957      0.20      0.00  |__Xorg
Average:     1000      2104         -      0.78      0.59  gnome-shell
Average:     1000         -      2104      0.78      0.59  |__gnome-shell
Average:     1000         -      2110      1.37      0.00  |__llvmpipe-0
Average:     1000         -      2111      1.56      0.00  |__llvmpipe-1
Average:     1000         -      2112      1.76      0.00  |__llvmpipe-2
Average:     1000         -      2113      1.37      0.00  |__llvmpipe-3
Average:     1000      2268         -      0.98      0.00  gsd-color
Average:     1000         -      2268      0.98      0.00  |__gsd-color
Average:     1000      2335         -     10.16      0.00  vmtoolsd
Average:     1000         -      2335     10.16      0.00  |__vmtoolsd
Average:     1000         -      2729      0.20      0.00  |__gmain
Average:     1000         -      2727      0.20      0.00  |__gmain
Average:        0      5480         -      1.37      0.00  kworker/2:1
Average:        0         -      5480      1.37      0.00  |__kworker/2:1
Average:        0      9193         -      0.98      0.00  kworker/1:0
Average:        0         -      9193      0.98      0.00  |__kworker/1:0
Average:        0      9224         -      1.17      0.00  kworker/3:0
Average:        0         -      9224      1.17      0.00  |__kworker/3:0
Average:        0     10778         -      7.62      0.00  kworker/u256:0
Average:        0         -     10778      7.62      0.00  |__kworker/u256:0
Average:        0     11010         -      0.98      0.00  kworker/0:4
Average:        0         -     11010      0.98      0.00  |__kworker/0:4
Average:        0     11946         -      1.95      0.00  kworker/u256:3
Average:        0         -     11946      1.95      0.00  |__kworker/u256:3
Average:     1000         -     11952  21298.44 184419.14  |__sysbench
Average:     1000         -     11953  19585.35 192591.21  |__sysbench
Average:     1000         -     11954  20186.52 173420.90  |__sysbench
Average:     1000         -     11955  20158.59 193855.27  |__sysbench
Average:     1000         -     11956  19719.34 178251.37  |__sysbench
Average:     1000         -     11957  20934.38 162003.52  |__sysbench
Average:     1000         -     11958  22238.48 162588.67  |__sysbench
Average:     1000         -     11959  19943.55 181168.75  |__sysbench
Average:     1000         -     11960  20675.00 177943.16  |__sysbench
Average:     1000         -     11961  20960.35 183560.94  |__sysbench
Average:     1000     11962         -      0.20    229.10  pidstat
Average:     1000         -     11962      0.20    229.49  |__pidstat

????????由上可知,該命令可以配合vmstat?使用, 因?yàn)?span style="background-color:#eff0f1;">vmstat?僅能描述系統(tǒng)整體的上下文切換信息。而pidstat可以精確到具體的線程或進(jìn)程。

通過(guò)pidstat 命令,我們確認(rèn)以下信息。

  1. 快速定位是由哪個(gè)進(jìn)程占用大部分CPU資源
  1. 快速定位是由哪個(gè)進(jìn)程/線程 發(fā)生了大量的上下文切換

dstat

????????dstat 是一個(gè)新的性能工具,它吸收了 vmstat、iostat、ifstat 等幾種工具的優(yōu)點(diǎn),可以同時(shí)觀察系統(tǒng)的 CPU、磁盤(pán) I/O、網(wǎng)絡(luò)以及內(nèi)存使用情況。?

yihua@ubuntu:~$ dstat 1 10
You did not select any stats, using -cdngy by default.
--total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read ?writ| recv ?send| ?in ??out | int ??csw
??0 ??1 ?99 ??0 ??0| ?15k ??12k| ??0 ????0 | ??0 ????0 |1186 ???24k
??0 ??0 100 ??0 ??0| ??0 ????0 | 120B ?178B| ??0 ????0 | ?80 ??111
??0 ??0 ?0 ??100 ?0| ?30M ???0 | 120B ?178B| ??0 ????0 | ?53 ???85
??0 ??0 100 ??0 ??0| ??0 ????0 | ?60B ?118B| ??0 ????0 | ?47 ???81
??0 ??0 100 ??0 ??0| ??0 ????0 | ?60B ?118B| ??0 ????0 | ?37 ???63
??0 ??0 100 ??0 ??0| ??0 ????0 | ?60B ?118B| ??0 ????0 | ?52 ???89
??1 ??0 ?99 ??0 ??0| ??0 ????0 | 120B ?178B| ??0 ????0 | ?79 ??198
??0 ??0 100 ??0 ??0| ??0 ????0 | 210B ?236B| ??0 ????0 | ?48 ???72
??0 ??0 100 ??0 ??0| ??0 ????0 | ?60B ?118B| ??0 ????0 | ?49 ???86
??0 ??0 100 ??0 ??0| ??0 ????0 | ?60B ?118B| ??0 ????0 | ?55 ???87

????????由上可知,當(dāng)I/O wait 為100%時(shí),分析 磁盤(pán) ,網(wǎng)卡,換頁(yè),中斷等數(shù)據(jù),可以得知當(dāng)前是在讀取磁盤(pán)的數(shù)據(jù)變慢了。造成了阻塞。

通過(guò)dstat 命令,可以確認(rèn)I/O的性能瓶頸具體產(chǎn)生在哪個(gè)硬件設(shè)備

perf

????????perf 是 Linux 2.6.31 以后內(nèi)置的性能分析工具。它以性能事件采樣為基礎(chǔ),不僅可以分析系統(tǒng)的各種事件和內(nèi)核性能,還可以用來(lái)分析指定應(yīng)用程序的性能問(wèn)題??梢詭椭覀冞M(jìn)一步定位具體的代碼或函數(shù)。

常用的方式有兩種。

  1. perf top,類(lèi)似于 top,它能夠?qū)崟r(shí)顯示占用 CPU 時(shí)鐘最多的函數(shù)或者指令,因此可以用來(lái)查找熱點(diǎn)函數(shù),使用界面如下所示:
SQL
Samples: 1K of event 'cpu-clock', Event count (approx.): 120772854
Overhead ?Shared Object ????????????????Symbol
??31.51% ?perf ?????????????????????????[.] d_demangle_callback
???9.68% ?[kernel] ?????????????????????[k] _raw_spin_unlock_irqrestore
???6.76% ?perf ?????????????????????????[.] __symbols__insert
???6.15% ?[kernel] ?????????????????????[k] mpt_put_msg_frame
???5.77% ?[kernel] ?????????????????????[k] __softirqentry_text_start
???5.68% ?libelf-0.170.so ??????????????[.] gelf_getsym
???3.82% ?perf ?????????????????????????[.] rb_next
???1.26% ?perf ?????????????????????????[.] rb_insert_color
???1.07% ?libc-2.27.so ?????????????????[.] _int_malloc
???1.04% ?libc-2.27.so ?????????????????[.] calloc
???0.90% ?[kernel] ?????????????????????[k] clear_page_orig
???0.87% ?[kernel] ?????????????????????[k] e1000_xmit_frame
???0.87% ?[kernel] ?????????????????????[k] exit_to_usermode_loop
???0.79% ?[kernel] ?????????????????????[k] radix_tree_next_chunk
???0.69% ?libmozjs-52.so.0.0.0 ?????????[.] JS::UnmarkGrayGCThingRecursively
???0.68% ?libc-2.27.so ?????????????????[.] __libc_malloc
???0.63% ?libmozjs-52.so.0.0.0 ?????????[.] js::UnsafeTraceManuallyBarrieredEdge<JSObject*>
???0.63% ?perf ?????????????????????????[.] dso__load_sym
???0.62% ?perf ?????????????????????????[.] __demangle_java_sym
???0.62% ?perf ?????????????????????????[.] java_demangle_sym
???0.49% ?[kernel] ?????????????????????[k] filemap_map_pages
???0.48% ?[kernel] ?????????????????????[k] get_page_from_freelist
???0.48% ?libc-2.27.so ?????????????????[.] __strrchr_avx2
???0.46% ?libelf-0.170.so ??????????????[.] elf_fill
???0.42% ?[kernel] ?????????????????????[k] finish_task_switch
???0.41% ?[kernel] ?????????????????????[k] __do_page_fault
???0.41% ?libelf-0.170.so ??????????????[.] gelf_update_verdaux
???0.39% ?libslang.so.2.3.1 ????????????[.] SLerrno_strerror
???0.35% ?libmozjs-52.so.0.0.0 ?????????[.] js::gc::EdgeNeedsSweep<jsid>
???0.35% ?[kernel] ?????????????????????[k] arch_local_irq_enable
???0.32% ?[kernel] ?????????????????????[k] queue_work_on
???0.32% ?[kernel] ?????????????????????[k] kallsyms_expand_symbol.constprop.1
???0.28% ?libc-2.27.so ?????????????????[.] __strlen_avx2
???0.27% ?perf ?????????????????????????[.] dso__find_symbol
???0.25% ?libc-2.27.so ?????????????????[.] __memcpy_avx_unaligned_erms
???0.25% ?[kernel] ?????????????????????[k] kmem_cache_alloc
???0.23% ?libelf-0.170.so ??????????????[.] gelf_getrela
???0.21% ?perf ?????????????????????????[.] cplus_demangle
???0.21% ?[kernel] ?????????????????????[k] handle_mm_fault
???0.21% ?containerd ???????????????????[.] fmt.(*pp).doPrintf
???0.21% ?libelf-0.170.so ??????????????[.] gelf_getphdr
???0.21% ?libpthread-2.27.so ???????????[.] pthread_mutex_init
???0.21% ?perf ?????????????????????????[.] arch__sym_update
???0.21% ?perf ?????????????????????????[.] elf_read_build_id
???0.21% ?perf ?????????????????????????[.] symbols__fixup_duplicate.part.2
???0.21% ?perf ?????????????????????????[.] symbols__fixup_end
???0.20% ?perf ?????????????????????????[.] dso__loaded
???0.20% ?[kernel] ?????????????????????[k] find_inode_fast
???0.20% ?libmozjs-52.so.0.0.0 ?????????[.] std::__adjust_heap<unsigned int*, long, unsigned int, __gnu_cxx::__ops::_Iter_less_iter>
???0.19% ?libc-2.27.so ?????????????????[.] cfree@GLIBC_2.2.5
???0.16% ?perf ?????????????????????????[.] map__find_symbol
???0.16% ?libmozjs-52.so.0.0.0 ?????????[.] js::SetWindowProxy
???0.16% ?[kernel] ?????????????????????[k] _raw_spin_lock
???0.15% ?[kernel] ?????????????????????[k] update_iter
???0.15% ?libvmtools.so.0.0.0 ??????????[.] Backdoor_InOut

????????由上可知,perf 中的 d_demangle_callback 函數(shù)被調(diào)用頻率較高,我們則可以從該接口入手,進(jìn)行優(yōu)化。

????????2. perf record?和 perf report。 perf top 雖然實(shí)時(shí)展示了系統(tǒng)的性能信息,但它的缺點(diǎn)是并不保存數(shù)據(jù),也就無(wú)法用于離線或者后續(xù)的分析。而 perf record 則提供了保存數(shù)據(jù)的功能,保存后的數(shù)據(jù),需要你用 perf report 解析展示。

SQL
yihua@ubuntu:~$ sudo perf record
^C[ perf record: Woken up 53 times to write data ]
[ perf record: Captured and wrote 14.481 MB perf.data (289019 samples) ]

yihua@ubuntu:~$ ls
c++ ?ekuiper-demo ?emqtt-bench ?emqx ?mi-ota ?nanoMQ ?perf.data ?presureTest ?sysstat ?test ?toolchain ?tranning ?vdi ?vsomeip
yihua@ubuntu:~$ perf report
failed to open perf.data: Permission denied
yihua@ubuntu:~$ sudo perf report

Samples: 289K of event 'cpu-clock', Event count (approx.): 72254750000
Overhead ?Command ?????????Shared Object ??????????????Symbol
??36.13% ?sysbench ????????[kernel.kallsyms] ??????????[k] _raw_spin_unlock_irqrestore
??26.80% ?swapper ?????????[kernel.kallsyms] ??????????[k] native_safe_halt
??11.08% ?sysbench ????????[kernel.kallsyms] ??????????[k] __schedule
???5.69% ?sysbench ????????[kernel.kallsyms] ??????????[k] finish_task_switch
???5.34% ?sysbench ????????[kernel.kallsyms] ??????????[k] do_syscall_64
???3.30% ?sysbench ????????[kernel.kallsyms] ??????????[k] sys_sched_yield
???3.10% ?sysbench ????????libpthread-2.27.so ?????????[.] pthread_mutex_unlock
???2.96% ?sysbench ????????libc-2.27.so ???????????????[.] sched_yield
???1.71% ?sysbench ????????libpthread-2.27.so ?????????[.] __pthread_mutex_lock
???0.62% ?sysbench ????????[kernel.kallsyms] ??????????[k] exit_to_usermode_loop
???0.58% ?sysbench ????????sysbench ???????????????????[.] crc32
???0.43% ?sysbench ????????[kernel.kallsyms] ??????????[k] schedule
???0.24% ?swapper ?????????[kernel.kallsyms] ??????????[k] finish_task_switch
???0.23% ?swapper ?????????[kernel.kallsyms] ??????????[k] tick_nohz_idle_enter
???0.20% ?sysbench ????????libpthread-2.27.so ?????????[.] __lll_lock_wait
???0.14% ?swapper ?????????[kernel.kallsyms] ??????????[k] __softirqentry_text_start
???0.12% ?swapper ?????????[kernel.kallsyms] ??????????[k] tick_nohz_idle_exit
???0.09% ?Xorg ????????????[kernel.kallsyms] ??????????[k] exit_to_usermode_loop
???0.08% ?sysbench ????????sysbench ???????????????????[.] pthread_yield@plt
???0.07% ?sysbench ????????[kernel.kallsyms] ??????????[k] futex_wake
???0.06% ?sysbench ????????[kernel.kallsyms] ??????????[k] futex_wait
???0.06% ?sysbench ????????libpthread-2.27.so ?????????[.] pthread_yield
???0.06% ?sysbench ????????[kernel.kallsyms] ??????????[k] sys_futex
???0.06% ?sysbench ????????libpthread-2.27.so ?????????[.] sched_yield@plt
???0.05% ?sysbench ????????[kernel.kallsyms] ??????????[k] futex_wait_queue_me
???0.05% ?sysbench ????????libpthread-2.27.so ?????????[.] __lll_unlock_wake
???0.04% ?sysbench ????????[kernel.kallsyms] ??????????[k] _raw_spin_lock
???0.04% ?sysbench ????????[kernel.kallsyms] ??????????[k] mark_wake_futex
???0.04% ?swapper ?????????[kernel.kallsyms] ??????????[k] do_idle
???0.04% ?sysbench ????????[kernel.kallsyms] ??????????[k] do_futex
???0.03% ?sysbench ????????libm-2.27.so ???????????????[.] __ieee754_log_fma
???0.03% ?sysbench ????????sysbench ???????????????????[.] pthread_mutex_unlock@plt
???0.03% ?sysbench ????????sysbench ???????????????????[.] sb_histogram_update
???0.03% ?sysbench ????????[kernel.kallsyms] ??????????[k] futex_wait_setup
???0.03% ?sysbench ????????sysbench ???????????????????[.] sb_event_stop
???0.03% ?sysbench ????????[kernel.kallsyms] ??????????[k] get_futex_key_refs.isra.11
???0.02% ?Xorg ????????????libpixman-1.so.0.34.0 ??????[.] _pixman_internal_only_get_implementation
???0.02% ?sysbench ????????[kernel.kallsyms] ??????????[k] __unqueue_futex
???0.02% ?sysbench ????????[kernel.kallsyms] ??????????[k] get_futex_value_locked
???0.02% ?nautilus-deskto ?[kernel.kallsyms] ??????????[k] exit_to_usermode_loop
???0.02% ?sysbench ????????[kernel.kallsyms] ??????????[k] hash_futex
???0.02% ?sysbench ????????[kernel.kallsyms] ??????????[k] get_futex_key
???0.02% ?swapper ?????????[kernel.kallsyms] ??????????[k] __schedule
???0.02% ?sysbench ????????[kernel.kallsyms] ??????????[k] __softirqentry_text_start
???0.02% ?swapper ?????????[kernel.kallsyms] ??????????[k] rcu_idle_exit
???0.02% ?sysbench ????????[kernel.kallsyms] ??????????[k] native_queued_spin_lock_slowpath
???0.02% ?sysbench ????????[kernel.kallsyms] ??????????[k] wake_q_add
???0.01% ?sysbench ????????libc-2.27.so ???????????????[.] clock_gettime
???0.01% ?sysbench ????????[kernel.kallsyms] ??????????[k] plist_add
???0.01% ?swapper ?????????[kernel.kallsyms] ??????????[k] arch_cpu_idle
???0.01% ?sysbench ????????[vdso] ?????????????????????[.] __vdso_clock_gettime
???0.01% ?sysbench ????????[kernel.kallsyms] ??????????[k] wake_up_q
???0.01% ?swapper ?????????[kernel.kallsyms] ??????????[k] __cpuidle_text_start
???0.01% ?swapper ?????????[kernel.kallsyms] ??????????[k] _raw_spin_unlock_irqrestore
???0.01% ?swapper ?????????[kernel.kallsyms] ??????????[k] schedule_idle

由上可知sysbench 進(jìn)程中的 內(nèi)核態(tài) 的 _raw_spin_unlock_irqrestore?接口調(diào)用最頻繁。

通過(guò)perf命令,可以快速定位到熱點(diǎn)代碼,幫助我們確定優(yōu)化范圍。

CPU性能分析定位套路

????????我們已經(jīng)知道了哪些場(chǎng)景會(huì)使用到CPU。執(zhí)行用戶(hù)態(tài)代碼執(zhí)行內(nèi)核態(tài)代碼,執(zhí)行中斷程序代碼,任務(wù)的上下文切換,進(jìn)程處于不可中斷狀態(tài)。定位相關(guān)場(chǎng)景的工具。top,vmstat,pidstat,dstat,perf

根據(jù)以上知識(shí)點(diǎn),當(dāng)我們遇到CPU 性能瓶頸時(shí),有一個(gè)快速定位問(wèn)題的套路。思路如下圖:

CPU性能優(yōu)化——“瑞士軍刀“,性能優(yōu)化,性能優(yōu)化

通過(guò)top命令,分析獲取系統(tǒng)整體的CPU資源消耗。判斷集中消耗在哪里,即關(guān)注以下信息。CPU性能優(yōu)化——“瑞士軍刀“,性能優(yōu)化,性能優(yōu)化

  1. 內(nèi)核態(tài)(sy)。系統(tǒng)內(nèi)核態(tài)占用比較高。有兩種情況:上下文切換頻繁,導(dǎo)致資源的消耗;進(jìn)程內(nèi)核代碼執(zhí)行頻繁,比如驅(qū)動(dòng)代碼,系統(tǒng)調(diào)用等。
    1. 通過(guò)vmstat 1 3?查看當(dāng)前系統(tǒng)上下文切換次數(shù)是否異常。若異常則說(shuō)明,大量的CPU資源消耗在上下文切換。
    2. 通過(guò)pidstat -uwt 1 10?查看當(dāng)前所有進(jìn)程占用的CPU 資源以及上下文切換頻率。確定異常進(jìn)程。
      1. 最終通過(guò)perf record+perf report定位熱點(diǎn)代碼塊
  2. 用戶(hù)態(tài)(us+ni)。若用戶(hù)態(tài)占用比較高,說(shuō)明程序中存在大量的計(jì)算。
    1. 通過(guò)pidstat -u 1 10?查看所有進(jìn)程占用的CPU資源,確定異常進(jìn)程
      1. 最終通過(guò)perf record+perf report定位熱點(diǎn)代碼塊。
  3. 硬中斷(hi)。硬中斷若占用比較高,存在兩種可能:中斷處理函數(shù)耗時(shí)較多;中斷源觸發(fā)頻繁。
    1. 通過(guò)vmstat 1 3?查看當(dāng)前系統(tǒng)中斷次數(shù)是否異常。若異常則說(shuō)明又由于真實(shí)的硬件中斷觸發(fā)導(dǎo)致的。
    2. 若中斷次數(shù)處于正常范圍,則說(shuō)明中斷處理接口可能出現(xiàn)了問(wèn)題。
      1. 通過(guò)cat /proc/interrupts?定位的中斷源,確認(rèn)頻率是否正?;蚍治鰧?duì)應(yīng)驅(qū)動(dòng)。
  4. 平均負(fù)載比較高。若負(fù)載比較高,直觀的現(xiàn)象就是,有些進(jìn)程可能運(yùn)行卡頓,比如ssh 客戶(hù)端。平均負(fù)載計(jì)算兩類(lèi)進(jìn)程:運(yùn)行狀態(tài)進(jìn)程,不可中斷狀態(tài)進(jìn)程。
    1. 通過(guò)vmstat 1 3?查看當(dāng)前運(yùn)行狀態(tài)和不可中斷狀態(tài)進(jìn)程數(shù)。若運(yùn)行狀態(tài)進(jìn)程數(shù)較多,則說(shuō)明當(dāng)前的確有很多進(jìn)程需要運(yùn)行,且是因?yàn)镃PU 資源性能不足。
      1. 針對(duì)這種情況,我們可以直接通過(guò)pidstat -u 1 5定位相關(guān)進(jìn)程。
    2. 若當(dāng)前不可中斷狀態(tài)進(jìn)程數(shù)較多,說(shuō)明當(dāng)前出現(xiàn)了I/O 瓶頸??赏ㄟ^(guò)dstat 1 10確認(rèn)磁盤(pán)讀寫(xiě),網(wǎng)絡(luò)收發(fā),內(nèi)存換頁(yè)等I/O瓶頸。
  5. 等待I/O比較高(wa)。與上述類(lèi)似,可通過(guò)dstat 1 10確認(rèn)磁盤(pán)讀寫(xiě),網(wǎng)絡(luò)收發(fā),內(nèi)存換頁(yè)等I/O瓶頸。
  6. 軟中斷(si)。可通過(guò)cat /proc/softirqs?查看是哪一類(lèi)軟中斷觸發(fā)頻繁。

????????以上的套路是我個(gè)人的理解,當(dāng)然還有一些其他場(chǎng)景沒(méi)有包含,但是應(yīng)該可以適用我們實(shí)際工作中90%的場(chǎng)景了。

常見(jiàn)的優(yōu)化措施

????????當(dāng)我們定位到CPU 性能瓶頸之后,下一步操作就是如何優(yōu)化。在這里根據(jù)分享一下我的經(jīng)驗(yàn),有好的場(chǎng)景或好的措施,也歡迎補(bǔ)充。

應(yīng)用程序優(yōu)化

若定位到性能瓶頸在用戶(hù)態(tài)代碼后,我們可以嘗試從以下幾方面入手。

  1. 編碼的角度。排除所有不必要的工作,只保留核心邏輯。比如減少循環(huán)的層次、減少遞歸、減少動(dòng)態(tài)內(nèi)存分配等等
  2. 編譯器優(yōu)化。很多編譯器都會(huì)提供編譯優(yōu)化選項(xiàng),適當(dāng)開(kāi)啟它們,在編譯階段可以獲得幫助。比如,gcc 提供了優(yōu)化選項(xiàng)-O2,開(kāi)啟之后會(huì)自動(dòng)對(duì)程序進(jìn)行優(yōu)化。
  3. 算法優(yōu)化。使用復(fù)雜度更低的算法,可以顯著提供運(yùn)算速度。比如在大數(shù)據(jù)量的情況下,使用O(nlogn)的排序算法,替換O(n^2)的冒泡算法等。
  4. 異步處理。使用異步處理,可以避免程序因?yàn)榈却硞€(gè)資源而一直阻塞,從而提升程序的并發(fā)處理能力。比如,輪詢(xún)事件改為事件通知,可以避免輪詢(xún)導(dǎo)致的CPU消耗。
  5. 多線程替換多進(jìn)程。這里主要就是節(jié)約線程上下文和進(jìn)程上下文切換的損耗了。
  6. 善用緩存,即空間換時(shí)間。經(jīng)常訪問(wèn)的數(shù)據(jù)或計(jì)算過(guò)程中的步驟,可以放在內(nèi)存中緩存起來(lái),加快內(nèi)存命中率,提高執(zhí)行速度。

內(nèi)核態(tài)程序優(yōu)化

????????若定位到性能瓶頸在內(nèi)核態(tài)之后,正常情況下,作為應(yīng)用開(kāi)發(fā)工程師,我們是無(wú)法去優(yōu)化內(nèi)核代碼的,當(dāng)然內(nèi)核代碼一般也很少有優(yōu)化空間。但并不代表我們就無(wú)計(jì)可施。可以嘗試從以下幾方面入手。

  1. CPU綁定。把進(jìn)程綁定到一個(gè)或者多個(gè)CPU上,可以提高CPU的緩存命中率,減少CPU調(diào)度帶來(lái)的上下文切換問(wèn)題。
  2. 優(yōu)先級(jí)調(diào)整:使用nice調(diào)整進(jìn)程的優(yōu)先級(jí),或修改進(jìn)程的調(diào)度策略。比如,適當(dāng)降低非核心應(yīng)用的優(yōu)先級(jí),增高核心應(yīng)用的優(yōu)先級(jí),可以確保核心應(yīng)用優(yōu)先被處理。
  3. 降低系統(tǒng)調(diào)用頻率:內(nèi)核態(tài)一般都是通過(guò)系統(tǒng)調(diào)用從用戶(hù)態(tài)進(jìn)入到內(nèi)核態(tài)。而系統(tǒng)調(diào)用也存在上下文的切換損耗,我們可以降低系統(tǒng)調(diào)用的頻率,從而減少損耗。比如用readv/writev替換read/write。

????????當(dāng)然以上的措施,在應(yīng)用程序優(yōu)化中,也可以使用。

硬中斷

????????若定位到性能瓶頸在硬中斷后,大概率就是環(huán)境出現(xiàn)了問(wèn)題,很少是驅(qū)動(dòng)異常。我們可以通過(guò)查看cat /proc/interrupts確定是哪類(lèi)中斷異常,再進(jìn)一步去排查。

I/O阻塞

????????若定位到性能瓶頸在I/O后,大概率就是硬件設(shè)備I/O性能不足導(dǎo)致的。我們一般可以從以下方面入手:

  1. 善用緩存。我們知道內(nèi)存的訪問(wèn)速度遠(yuǎn)遠(yuǎn)大于對(duì)磁盤(pán)的訪問(wèn)速度,我們可以使用緩沖區(qū),減少實(shí)際的磁盤(pán)或網(wǎng)絡(luò)I/O。比如,讀寫(xiě)磁盤(pán)操作中,我們盡量不使用O_DIRECT參數(shù),它表示繞過(guò)系統(tǒng)緩存,直接對(duì)磁盤(pán)進(jìn)行讀寫(xiě)。
  2. 優(yōu)化磁盤(pán)I/O。提升硬件性能,比如使用SSD;優(yōu)化文件系統(tǒng),比如使用ext4或XF5。提高成本。
  3. 引入提高I/O性能技術(shù)。比如引入iotadma技術(shù)。技術(shù)難度大。

軟中斷

????????若定位到性能瓶頸在軟中斷后,大概率也是環(huán)境問(wèn)題,很少是驅(qū)動(dòng)異常。具體的原因可以通過(guò)查看cat /proc/softirqs確定是哪一類(lèi)軟中斷異常,再進(jìn)一步去排查,處理。

$ watch -d cat /proc/softirqs
????????????????????CPU0 ??????CPU1
??????????HI: ?????????0 ?????????0
???????TIMER: ???1083906 ???2368646
??????NET_TX: ????????53 ?????????9
??????NET_RX: ???1550643 ???1916776
???????BLOCK: ?????????0 ?????????0
????IRQ_POLL: ?????????0 ?????????0
?????TASKLET: ????333637 ??????3930
???????SCHED: ????963675 ???2293171
?????HRTIMER: ?????????0 ?????????0
?????????RCU: ???1542111 ???1590625

????????比如,經(jīng)過(guò)分析,發(fā)現(xiàn)上圖中NET_RX,也就是網(wǎng)絡(luò)數(shù)據(jù)包接收軟中斷的變化速率最快。而其他幾種類(lèi)型的軟中斷,是保證 Linux 調(diào)度、時(shí)鐘和臨界區(qū)保護(hù)這些正常工作所必需的,所以它們有一定的變化倒是正常的。那么就可以確認(rèn)是網(wǎng)卡接收數(shù)據(jù)出現(xiàn)了異常。

????????再深入分析,可能就可以結(jié)合tcpdump命令,進(jìn)行抓包,查看是哪一個(gè)數(shù)據(jù)包一直發(fā)送。從而定位到問(wèn)題原因。比如SYN FLOOD問(wèn)題 就會(huì)導(dǎo)致上述問(wèn)題。

????????處理方式:從交換機(jī)或硬件防火墻中封掉來(lái)源IP,這樣SYN FLOOD網(wǎng)絡(luò)幀就不會(huì)收到了。

總結(jié)

? ? ? ? 當(dāng)出現(xiàn)CPU性能問(wèn)題時(shí),我們第一時(shí)間往往是手足無(wú)措,不知從何下手。本身深深體驗(yàn)過(guò)這種感受,確實(shí)不好受。因此希望本文能夠幫助到正在經(jīng)歷這種痛苦的朋友。有好的案例或者場(chǎng)景也可以分享,討論。共勉~

?若我的內(nèi)容對(duì)您有所幫助,還請(qǐng)關(guān)注我的公眾號(hào)。不定期分享干活,剖析案例,也可以一起討論分享。
我的宗旨:
踩完您工作中的所有坑并分享給您,讓你的工作無(wú)bug,人生盡是坦途

CPU性能優(yōu)化——“瑞士軍刀“,性能優(yōu)化,性能優(yōu)化

CPU性能優(yōu)化——“瑞士軍刀“,性能優(yōu)化,性能優(yōu)化文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-744659.html

到了這里,關(guān)于CPU性能優(yōu)化——“瑞士軍刀“的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 開(kāi)發(fā)者的瑞士軍刀!一款適用于開(kāi)發(fā)者的工具集合!

    大家好,我是 Java陳序員 。 俗話說(shuō)“工欲善其事必先利其器”,有一個(gè)好的工具可以事半功倍。 編程開(kāi)發(fā)亦是如此。 今天,給大家介紹一款離線的 Windows 應(yīng)用程序,該應(yīng)用涵蓋常見(jiàn)的開(kāi)發(fā)工具集合,旨在提高工作效率! 關(guān)注微信公眾號(hào):【Java陳序員】,獲取 開(kāi)源項(xiàng)目分享

    2024年01月22日
    瀏覽(27)
  • x-cmd pkg | busybox - 嵌入式 Linux 的瑞士軍刀

    x-cmd pkg | busybox - 嵌入式 Linux 的瑞士軍刀

    busybox 是一個(gè)開(kāi)源的輕量級(jí)工具集合,集成了一批最常用 Unix 工具命令,只需要幾 MB 大小就能覆蓋絕大多數(shù)用戶(hù)在 Linux 的使用,能在多款 POSIX 環(huán)境的操作系統(tǒng)(如 Linux、Windows、Android、嵌入式系統(tǒng))中運(yùn)行,被稱(chēng)為 “嵌入式 Linux 的瑞士軍刀” 。 它是一個(gè)開(kāi)源項(xiàng)目,遵循

    2024年01月20日
    瀏覽(96)
  • 「GitHub資源」DevToys開(kāi)發(fā)者神器,堪稱(chēng)程序員界的瑞士軍刀!

    「GitHub資源」DevToys開(kāi)發(fā)者神器,堪稱(chēng)程序員界的瑞士軍刀!

    如果你是一個(gè) Windows 開(kāi)發(fā)者,你是否經(jīng)常需要在網(wǎng)上搜索一些工具來(lái)完成一些簡(jiǎn)單的任務(wù),比如 格式化 JSON , 比較文本 ,測(cè)試 正則表達(dá)式 ,轉(zhuǎn)換 數(shù)據(jù)類(lèi)型 , 生成二維碼 , 編碼解碼字符串 等等?你是否擔(dān)心把你的數(shù)據(jù)粘貼到一些不可靠的網(wǎng)站上會(huì)有安全風(fēng)險(xiǎn)?你是否想

    2024年02月22日
    瀏覽(22)
  • 性能優(yōu)化(CPU優(yōu)化技術(shù))-NEON 介紹

    性能優(yōu)化(CPU優(yōu)化技術(shù))-NEON 介紹

    「發(fā)表于知乎專(zhuān)欄《移動(dòng)端算法優(yōu)化》」 本節(jié)主要介紹基本 SIMD 及其他的指令流與數(shù)據(jù)流的處理方式,NEON 的基本原理、指令以及與其他平臺(tái)及硬件的對(duì)比。 ??個(gè)人簡(jiǎn)介:一個(gè)全棧工程師的升級(jí)之路! ??個(gè)人專(zhuān)欄:高性能(HPC)開(kāi)發(fā)基礎(chǔ)教程 ??CSDN主頁(yè)?發(fā)狂的小花 ??人

    2024年01月24日
    瀏覽(16)
  • 性能優(yōu)化(CPU優(yōu)化技術(shù))-NEON指令介紹

    性能優(yōu)化(CPU優(yōu)化技術(shù))-NEON指令介紹

    「發(fā)表于知乎專(zhuān)欄《移動(dòng)端算法優(yōu)化》」 本文主要介紹了 NEON 指令相關(guān)的知識(shí),首先通過(guò)講解 arm 指令集的分類(lèi),NEON寄存器的類(lèi)型,樹(shù)立基本概念。然后進(jìn)一步梳理了 NEON 匯編以及 intrinsics 指令的格式。最后結(jié)合指令的分類(lèi),使用例子講述 NEON 指令的使用方法。 ??個(gè)人簡(jiǎn)介

    2024年01月24日
    瀏覽(23)
  • CPU和GPU性能優(yōu)化

    在Unity游戲開(kāi)發(fā)中,優(yōu)化CPU和GPU的性能是非常重要的,可以提高游戲的運(yùn)行效率、降低功耗和延遲,并提高用戶(hù)體驗(yàn)。以下是一些優(yōu)化CPU和GPU性能的方法: 1.優(yōu)化游戲邏輯和算法 減少不必要的計(jì)算和內(nèi)存操作,例如避免頻繁的分配和釋放內(nèi)存,減少不必要的數(shù)據(jù)結(jié)構(gòu)和循環(huán)。

    2024年02月09日
    瀏覽(18)
  • RK3588 CPU性能優(yōu)化

    CPU負(fù)載的采樣時(shí)間關(guān)系到CPU的變頻和大小核調(diào)度的及時(shí)性,目前系統(tǒng)的默認(rèn)配置是32ms,可以通過(guò)如下節(jié)點(diǎn)獲?。?目前的采用時(shí)間可以設(shè)置為32ms和8ms,在8ms的情況下cpu的負(fù)載變頻和大小核調(diào)度會(huì)更及時(shí),但是同時(shí)功耗也會(huì)對(duì)應(yīng)的增加; 可以通過(guò)如下命令進(jìn)行設(shè)置: 如果要在

    2024年02月12日
    瀏覽(17)
  • Linux性能優(yōu)化實(shí)踐——CPU上下文

    Linux性能優(yōu)化實(shí)踐——CPU上下文

    Linux是一個(gè)多任務(wù)操作系統(tǒng),它支持遠(yuǎn)大于CPU數(shù)量的任務(wù)同時(shí)運(yùn)行。這些任務(wù)不是真正意義上的并行運(yùn)行,而是系統(tǒng)在短時(shí)間內(nèi),將CPU輪流分配給它們,造成任務(wù)同時(shí)運(yùn)行的錯(cuò)覺(jué)。 CPU需要知道任務(wù)從哪里加載,從哪里開(kāi)始運(yùn)行是通過(guò)設(shè)置好的CPU寄存器和程序計(jì)數(shù)器(Program C

    2024年02月13日
    瀏覽(28)
  • Android 性能優(yōu)化 命令行查看CPU使用率

    本文介紹cpu使用率概念,和使用ps命令、top命令和dumpsys cpuinfo命令來(lái)查看cpu使用率,幫助我們了解應(yīng)用程序在運(yùn)行過(guò)程中的整體狀態(tài)和各個(gè)線程狀態(tài)。 CPU利用率指系統(tǒng)中CPU的使用情況,通常以百分比表示CPU使用率。 在多核情況下,CPU使用率指的是所有核心的平均使用率。 通

    2024年02月05日
    瀏覽(25)
  • 記1次前端性能優(yōu)化之CPU使用率

    記1次前端性能優(yōu)化之CPU使用率

    碰到這樣的一個(gè)問(wèn)題,用戶(hù)反饋?lái)?yè)面的圖表一直加載不出來(lái),頁(yè)面還卡死 打開(kāi)鏈接頁(yè)面,打開(kāi)控制臺(tái) Network 看到有個(gè)請(qǐng)求一直pending,結(jié)合用戶(hù)描述,頁(yè)面一直loading,似乎驗(yàn)證了我的懷疑:后端遲遲沒(méi)有相應(yīng)。 但是,還有個(gè)現(xiàn)象,頁(yè)面卡死了,后端沒(méi)響應(yīng)怎么能導(dǎo)致頁(yè)面卡死

    2024年02月10日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包