1024程序員節(jié)獻(xiàn)禮鯤鵬性能優(yōu)化十板斧(二)——CPU與內(nèi)存子系統(tǒng)性能調(diào)優(yōu)

      網(wǎng)友投稿 1173 2022-05-29

      1.1 CPU與內(nèi)存子系統(tǒng)性能調(diào)優(yōu)簡(jiǎn)介

      調(diào)優(yōu)思路

      性能優(yōu)化的思路如下:

      l?? 如果CPU的利用率不高,說(shuō)明資源沒(méi)有充分利用,可以通過(guò)工具(如strace)查看應(yīng)用程序阻塞在哪里,一般為磁盤(pán),網(wǎng)絡(luò)或應(yīng)用程序的業(yè)務(wù)處理中存在休眠或信號(hào)等待,這些優(yōu)化措施在后續(xù)其它章節(jié)描述。

      l?? 如果CPU利用率高,通過(guò)優(yōu)化軟件硬件的配置參數(shù)來(lái)更好適配業(yè)務(wù)場(chǎng)景,減少CPU占用率,讓整個(gè)系統(tǒng)有更多的CPU時(shí)間來(lái)處理業(yè)務(wù)。

      我們也可以選擇更好的硬件,根據(jù)CPU的能力配置合適的內(nèi)存條,建議內(nèi)存滿通道配置,發(fā)揮內(nèi)存最大帶寬:一顆鯤鵬920處理器的內(nèi)存通道數(shù)為8,兩顆鯤鵬920處理器的內(nèi)存通道數(shù)為16;建議選擇高頻率的內(nèi)存條,提升內(nèi)存帶寬:鯤鵬920在1DPC配置時(shí),支持的內(nèi)存最高頻率為2933MHz。

      主要優(yōu)化參數(shù)

      優(yōu)化項(xiàng)

      優(yōu)化項(xiàng)簡(jiǎn)介

      默認(rèn)值

      生效范圍

      鯤鵬916

      鯤鵬920

      優(yōu)化應(yīng)用程序的NUMA配置

      在NUMA架構(gòu)下,CPU core訪問(wèn)臨近的內(nèi)存時(shí)訪問(wèn)延遲更低。將應(yīng)用程序綁在一個(gè)NUMA節(jié)點(diǎn),可減少因訪問(wèn)遠(yuǎn)端內(nèi)存帶來(lái)的性能下降。

      默認(rèn)不綁定核

      立即生效

      yes

      yes

      修改CPU預(yù)取開(kāi)關(guān)

      內(nèi)存預(yù)取在數(shù)據(jù)集中場(chǎng)景下可以提前將要訪問(wèn)的數(shù)據(jù)讀到CPU cache 中,提升性能;若數(shù)據(jù)不集中,導(dǎo)致預(yù)取命中率低,則浪費(fèi)內(nèi)存帶寬。

      on

      重啟生效

      no

      yes

      調(diào)整定時(shí)器機(jī)制

      nohz機(jī)制可減少不必要的時(shí)鐘中斷,減少CPU調(diào)度開(kāi)銷。

      不同OS默認(rèn)配置不同

      Euler:nohz=off

      重啟生效

      yes

      yes

      調(diào)整內(nèi)存的頁(yè)大小為64K

      內(nèi)存的頁(yè)大小越大,TLB中每行管理的內(nèi)存越多,TLB命中率就越高,從而減少內(nèi)存訪問(wèn)次數(shù)。

      不同OS默認(rèn)配置不同:

      4KB或64K

      重新編譯內(nèi)核、更新內(nèi)核后生效

      yes

      yes

      優(yōu)化應(yīng)用程序的線程并發(fā)數(shù)

      適當(dāng)調(diào)整應(yīng)用的線程并發(fā)數(shù),使得充分利用多核能力和資源爭(zhēng)搶之間達(dá)到平衡。

      由應(yīng)用本身決定

      立即生效或重啟生效(由應(yīng)用決定)

      yes

      yes

      1.2 常用性能監(jiān)測(cè)工具

      1.2.1 top工具

      介紹

      top是最常用的Linux性能監(jiān)測(cè)工具之一。通過(guò)top工具可以監(jiān)視進(jìn)程和系統(tǒng)整體性能。

      命令參考舉例:

      命令

      說(shuō)明

      top

      查看系統(tǒng)整體的CPU、內(nèi)存資源消耗。

      top執(zhí)行后輸入1

      查看每個(gè)CPU core資源使用情況。

      top執(zhí)行后輸入F,并選擇P選項(xiàng)

      查看線程執(zhí)行過(guò)程中是否調(diào)度到其它CPU core。

      top -p $PID -H

      查看某個(gè)進(jìn)程內(nèi)所有線程的CPU資源占用。

      安裝方式

      系統(tǒng)自帶,無(wú)需安裝。

      使用方法

      步驟 1????? 使用top命令統(tǒng)計(jì)整體CPU、內(nèi)存資源消耗。

      l?? CPU項(xiàng):顯示當(dāng)前總的CPU時(shí)間使用分布。

      us表示用戶態(tài)程序占用的CPU時(shí)間百分比。

      sy表示內(nèi)核態(tài)程序所占用的CPU時(shí)間百分比。

      wa表示等待IO等待占用的CPU時(shí)間百分比。

      hi表示硬中斷所占用的CPU時(shí)間百分比。

      si表示軟中斷所占用的CPU時(shí)間百分比。

      通過(guò)這些參數(shù)我們可以分析CPU時(shí)間的分布,是否有較多的IO等待。在執(zhí)行完調(diào)優(yōu)步驟后,我們也可以對(duì)CPU使用時(shí)間進(jìn)行前后對(duì)比。如果在運(yùn)行相同程序、業(yè)務(wù)情況下CPU使用時(shí)間降低,說(shuō)明性能有提升。

      l?? KiB Mem:表示服務(wù)器的總內(nèi)存大小以及使用情況。

      l?? KiB Swap:表示當(dāng)前所使用的Swap空間的大小。Swap空間即當(dāng)內(nèi)存不足的時(shí)候,把一部分硬盤(pán)空間虛擬成內(nèi)存使用。如果當(dāng)前所使用的Swap空間大于0,可以考慮優(yōu)化應(yīng)用的內(nèi)存占用或增加物理內(nèi)存。

      步驟 2????? 在top命令執(zhí)行后按1,查看每個(gè)CPU core的使用情況。

      通過(guò)該命令可以查看單個(gè)CPU core的使用情況,如果CPU占用集中在某幾個(gè)CPU core上,可以結(jié)合業(yè)務(wù)分析觸發(fā)原因,從而找到優(yōu)化思路。

      步驟 3????? 選中top命令的P選項(xiàng),查看線程運(yùn)行在哪些 CPU core上。

      在top命令執(zhí)行后按F,可以進(jìn)入top命令管理界面。在該界面通過(guò)上下鍵移動(dòng)光標(biāo)到P選項(xiàng),通過(guò)空格鍵選中后按Esc退出,即可顯示出線程運(yùn)行的CPU核。觀察一段時(shí)間,若業(yè)務(wù)線程在不同NUMA節(jié)點(diǎn)內(nèi)的CPU core上運(yùn)行,則說(shuō)明存在較多的跨NUMA訪問(wèn),可通過(guò)NUMA綁核進(jìn)行優(yōu)化。

      步驟 4????? 使用top -p $PID -H命令觀察進(jìn)程中每個(gè)線程的CPU資源使用。

      “-p”后接的參數(shù)為待觀察的進(jìn)程ID。通過(guò)該命令可以找出消耗資源多的線程,隨后可根據(jù)線程號(hào)分析線程中的熱點(diǎn)函數(shù)、調(diào)用過(guò)程等情況。

      ----結(jié)束

      1.2.2 Perf工具

      介紹

      Perf工具是非常強(qiáng)大的Linux性能分析工具,可以通過(guò)該工具獲得進(jìn)程內(nèi)的調(diào)用情況、資源消耗情況并查找分析熱點(diǎn)函數(shù)。

      命令參考舉例:

      命令

      說(shuō)明

      perf top

      查看當(dāng)前系統(tǒng)中的熱點(diǎn)函數(shù)。

      perf sched record -- sleep 1 -p $PID

      記錄進(jìn)程在1s內(nèi)的系統(tǒng)調(diào)用。

      perf sched latency --sort max

      查看上一步記錄的結(jié)果,以調(diào)度延遲排序。

      安裝方式

      以CentOS為例,使用如下命令安裝:

      # yum -y install perf

      使用方法

      步驟 1????? 通過(guò)perf top命令查找熱點(diǎn)函數(shù)。

      該命令統(tǒng)計(jì)各個(gè)函數(shù)在某個(gè)性能事件上的熱度,默認(rèn)顯示CPU占用率,可以通過(guò)“-e”監(jiān)控其它事件。

      l?? Overhead表示當(dāng)前事件在全部事件中占的比例。

      l?? Shared Object表示當(dāng)前事件生產(chǎn)者,如kernel、perf命令、C語(yǔ)言庫(kù)函數(shù)等。

      l?? Symbol則表示熱點(diǎn)事件對(duì)應(yīng)的函數(shù)名稱。

      通過(guò)熱點(diǎn)函數(shù),我們可以找到消耗資源較多的行為,從而有針對(duì)性的進(jìn)行優(yōu)化。

      步驟 2????? 收集一段時(shí)間內(nèi)的線程調(diào)用。

      perf sched record命令用于記錄一段時(shí)間內(nèi),進(jìn)程的調(diào)用情況。“-p”后接進(jìn)程號(hào),“sleep”后接統(tǒng)計(jì)時(shí)長(zhǎng),單位為秒。收集到的信息自動(dòng)存放在當(dāng)前目錄下,文件名為perf.data。

      步驟 3????? 解析收集到的線程調(diào)度信息。

      perf sched latency命令可以解析當(dāng)前目錄下的perf.data文件。“-s”表示進(jìn)行排序,后接參數(shù)“max”表示按照最大延遲時(shí)間大小排序。

      ----結(jié)束

      1.2.3 numactl工具

      介紹

      numactl工具可用于查看當(dāng)前服務(wù)器的NUMA節(jié)點(diǎn)配置、狀態(tài),可通過(guò)該工具將進(jìn)程綁定到指定CPU core,由指定CPU core來(lái)運(yùn)行對(duì)應(yīng)進(jìn)程。

      命令參考舉例:

      命令

      說(shuō)明

      numactl -H

      查看當(dāng)前服務(wù)器的NUMA配置。

      numactl -C 0-7 ./test

      將應(yīng)用程序test綁定到0~7核運(yùn)行。

      numastat

      查看當(dāng)前的NUMA運(yùn)行狀態(tài)。

      安裝方式

      以CentOS為例,使用如下命令安裝:

      # yum -y install numactl numastat

      使用方法

      步驟 1????? 通過(guò)numactl查看當(dāng)前服務(wù)器的NUMA配置。

      從numactl執(zhí)行結(jié)果可以看到,示例服務(wù)器共劃分為4個(gè)NUMA節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)包含16個(gè)CPU core,每個(gè)節(jié)點(diǎn)的內(nèi)存大小約為64GB。同時(shí),該命令還給出了不同節(jié)點(diǎn)間的距離,距離越遠(yuǎn),跨NUMA內(nèi)存訪問(wèn)的延時(shí)越大。應(yīng)用程序運(yùn)行時(shí)應(yīng)減少跨NUMA訪問(wèn)內(nèi)存。

      步驟 2????? 通過(guò)numactl將進(jìn)程綁定到指定CPU core。

      通過(guò) numactl -C 0-15 top 命令即是將進(jìn)程“top”綁定到0~15 CPU core上執(zhí)行。

      步驟 3????? 通過(guò)numastat查看當(dāng)前NUMA節(jié)點(diǎn)的內(nèi)存訪問(wèn)命中率。

      可以通過(guò)numastat命令觀察各個(gè)NUMA節(jié)點(diǎn)的狀態(tài)。

      l?? numa_hit表示節(jié)點(diǎn)內(nèi)CPU核訪問(wèn)本地內(nèi)存的次數(shù)。

      l?? numa_miss表示節(jié)點(diǎn)內(nèi)核訪問(wèn)其他節(jié)點(diǎn)內(nèi)存的次數(shù)。跨節(jié)點(diǎn)的內(nèi)存訪問(wèn)會(huì)存在高延遲從而降低性能,因此,numa_miss的值應(yīng)當(dāng)越低越好,如果過(guò)高,則應(yīng)當(dāng)考慮綁核。

      ----結(jié)束

      1.3 優(yōu)化方法

      1.3.1 NUMA優(yōu)化,減少跨NUMA訪問(wèn)內(nèi)存

      原理

      通過(guò)1.1 鯤鵬處理器NUMA簡(jiǎn)介章節(jié)可以看到不同NUMA內(nèi)的CPU core訪問(wèn)同一個(gè)位置的內(nèi)存,性能不同。內(nèi)存訪問(wèn)延時(shí)從高到低為:跨CPU > 跨NUMA不跨CPU > NUMA內(nèi)

      因此在應(yīng)用程序運(yùn)行時(shí)要盡可能的避免跨NUMA訪問(wèn)內(nèi)存,我們可以通過(guò)設(shè)置線程的CPU親和性來(lái)實(shí)現(xiàn)。

      修改方式

      l?? 網(wǎng)絡(luò)可以通過(guò)如下方式綁定運(yùn)行的CPU core,其中$cpuMask是16進(jìn)制的數(shù),最右邊的bit表示core0;$irq為網(wǎng)卡隊(duì)列中斷號(hào)。

      echo $cpuMask > /proc/irq/$irq/smp_affinity_list

      l?? 通過(guò)numactl啟動(dòng)程序,如下面的啟動(dòng)命令表示啟動(dòng)test程序,只能在CPU core 28到core31運(yùn)行(-C控制)。

      numactl -C 28-31 ./test

      l?? 在C/C++代碼中通過(guò)sched_setaffinity函數(shù)來(lái)設(shè)置線程親和性。

      l?? 很多開(kāi)源軟件已經(jīng)支持在自帶的配置文件中修改線程的親和性,例如nginx可以修改nginx.conf文件中的worker_cpu_affinity參數(shù)來(lái)設(shè)置nginx線程親和性。

      1.3.2 修改CPU的預(yù)取開(kāi)關(guān)

      原理

      局部性原理分為時(shí)間局部性原理和空間局部性原理:

      l?? 時(shí)間局部性原理(temporal locality):如果某個(gè)數(shù)據(jù)項(xiàng)被訪問(wèn),那么在不久的將來(lái)它可能再次被訪問(wèn)。

      l?? 空間局部性原理(spatial locality):如果某個(gè)數(shù)據(jù)項(xiàng)被訪問(wèn),那么與其地址相鄰的數(shù)據(jù)項(xiàng)可能很快也會(huì)被訪問(wèn)。

      CPU將內(nèi)存中的數(shù)據(jù)讀到CPU的高速緩沖Cache時(shí),會(huì)根據(jù)局部性原理,除了讀取本次要訪問(wèn)的數(shù)據(jù),還會(huì)預(yù)取本次數(shù)據(jù)的周邊數(shù)據(jù)到Cache里面,如果預(yù)取的數(shù)據(jù)是下次要訪問(wèn)的數(shù)據(jù),那么性能會(huì)提升,如果預(yù)取的數(shù)據(jù)不是下次要取的數(shù)據(jù),那么會(huì)浪費(fèi)內(nèi)存帶寬。

      對(duì)于數(shù)據(jù)比較集中的場(chǎng)景,預(yù)取的命中率高,適合打開(kāi)CPU預(yù)取,反之需要關(guān)閉CPU預(yù)取。目前發(fā)現(xiàn)speccpu和X265軟件場(chǎng)景適合打開(kāi)CPU預(yù)取,STREAM測(cè)試工具、Nginx和數(shù)據(jù)庫(kù)場(chǎng)景需要關(guān)閉CPU預(yù)取。

      修改方式

      按照B 進(jìn)入BIOS界面的步驟進(jìn)入BIOS,然后在BIOS的如下位置設(shè)置CPU的預(yù)取開(kāi)關(guān)。

      1.3.3 定時(shí)器機(jī)制調(diào)整,減少不必要的時(shí)鐘中斷

      原理

      在Linux內(nèi)核2.6.17版本之前,Linux內(nèi)核為每個(gè)CPU設(shè)置一個(gè)周期性的時(shí)鐘中斷,Linux內(nèi)核利用這個(gè)中斷處理一些定時(shí)任務(wù),如線程調(diào)度等。這樣導(dǎo)致就算CPU不需要定時(shí)器的時(shí)候,也會(huì)有很多時(shí)鐘中斷,導(dǎo)致資源的浪費(fèi)。Linux 內(nèi)核2.6.17版本引入了nohz機(jī)制,實(shí)際就是讓時(shí)鐘中斷的時(shí)間可編程,減少不必要的時(shí)鐘中斷。

      修改方式

      執(zhí)行cat /proc/cmdline查看Linux 內(nèi)核的啟動(dòng)參數(shù),如果有nohz=off關(guān)鍵字,說(shuō)明nohz機(jī)制被關(guān)閉,需要打開(kāi)。修改方法如下:

      修改前后,可以通過(guò)如下命令觀察timer_tick的調(diào)度次數(shù),其中$PID為要觀察的進(jìn)程ID,可以選擇CPU占用高的進(jìn)程進(jìn)行觀察:

      perf sched record -- sleep 1 -p $PID

      perf sched latency -s max

      輸出信息中有如下信息,其中591字段表示統(tǒng)計(jì)時(shí)間內(nèi)的調(diào)度次數(shù),數(shù)字變小說(shuō)明修改生效。

      timer_tick:(97) | 7.364 ms | 591 | avg: 0.012 ms | max: 1.268 ms

      步驟 1????? 在“/boot”目錄下通過(guò)find -name grub.cfg找到啟動(dòng)參數(shù)的配置文件。

      步驟 2????? 在配置文件中將nohz=off去掉。

      【1024程序員節(jié)獻(xiàn)禮】鯤鵬性能優(yōu)化十板斧(二)——CPU與內(nèi)存子系統(tǒng)性能調(diào)優(yōu)

      步驟 3????? 重啟服務(wù)器。

      ----結(jié)束

      1.3.4 調(diào)整內(nèi)存頁(yè)的大小為64K,提升TLB命中率

      原理

      TLB(Translation lookaside buffer)為頁(yè)表(存放虛擬地址的頁(yè)地址和物理地址的頁(yè)地址的映射關(guān)系)在CPU內(nèi)部的高速緩存。TLB的命中率越高,頁(yè)表查詢性能就越好。

      TLB的一行為一個(gè)頁(yè)的映射關(guān)系,也就是管理了一個(gè)頁(yè)大小的內(nèi)存:

      TLB管理的內(nèi)存大小 = TLB行數(shù) x 內(nèi)存的頁(yè)大小

      同一個(gè)CPU的TLB行數(shù)固定,因此內(nèi)存頁(yè)越大,管理的內(nèi)存越大,相同業(yè)務(wù)場(chǎng)景下的TLB命中率就越高。

      修改方式

      修改Linux內(nèi)核編譯選項(xiàng),并重新編譯:

      修改前后可以通過(guò)如下命令觀察TLB的命中率($PID為進(jìn)程ID):

      perf stat -p $PID -d -d -d

      輸出結(jié)果包含如下信息,其中1.21%和0.59%分別表示數(shù)據(jù)的miss率和指令的miss率。

      1,090,788,717????? dTLB-loads??????????????? #? 520.592 M/sec

      13,213,603????? dTLB-load-misses????????? #??? 1.21% of all dTLB cache hits

      669,485,765????? iTLB-loads??????????????? #? 319.520 M/sec

      3,979,246????? iTLB-load-misses????????? #??? 0.59% of all iTLB cache hits

      步驟 1????? 執(zhí)行make menuconfig。

      步驟 2????? 選擇PAGESIZE大小為64K。

      Kernel Features-->Page size(64KB)

      步驟 3????? 編譯和安裝內(nèi)核。

      參考https://bbs.huaweicloud.com/forum/thread-24362-1-1.html

      ----結(jié)束

      1.3.5 調(diào)整線程并發(fā)數(shù)

      原理

      程序從單線程變?yōu)槎嗑€程時(shí),CPU和內(nèi)存資源得到充分利用,性能得到提升。但是系統(tǒng)的性能并不會(huì)隨著線程數(shù)的增長(zhǎng)而線性提升,因?yàn)殡S著線程數(shù)量的增加,線程之間的調(diào)度、上下文切換、關(guān)鍵資源和鎖的競(jìng)爭(zhēng)也會(huì)帶來(lái)很大開(kāi)銷。當(dāng)資源的爭(zhēng)搶比較嚴(yán)重時(shí),甚至?xí)?dǎo)致性能明顯降。下面數(shù)據(jù)為某業(yè)務(wù)場(chǎng)景下,不同并發(fā)線程數(shù)下的TPS,可以看到并發(fā)線程數(shù)達(dá)到128后,性能達(dá)到高峰,隨后開(kāi)始下降。我們需要針對(duì)不同的業(yè)務(wù)模型和使用場(chǎng)景做多組測(cè)試,找到適合本業(yè)務(wù)場(chǎng)景的最佳并發(fā)線程數(shù)。

      修改方式

      不同的軟件有不同的配置,需要根據(jù)代碼實(shí)現(xiàn)來(lái)修改,這里舉例幾個(gè)常用開(kāi)源軟件的修改方法:

      MySql可以通過(guò)innodb_thread_concurrency設(shè)置工作線程的最大并發(fā)數(shù)。

      Nginx可以通過(guò)worker_processes參數(shù)設(shè)置并發(fā)的進(jìn)程個(gè)數(shù)。

      下一篇:網(wǎng)絡(luò)子系統(tǒng)性能調(diào)優(yōu),敬請(qǐng)期待

      鯤鵬

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:ROS1/2機(jī)器人之從命令調(diào)用到程序編寫(xiě)
      下一篇:【精選單品】基于互聯(lián)網(wǎng)技術(shù)的智慧門店,如何完成實(shí)體與虛擬消費(fèi)體驗(yàn)的對(duì)接?
      相關(guān)文章
      午夜亚洲国产理论片二级港台二级| 亚洲av午夜精品无码专区| 亚洲a∨无码精品色午夜| 激情内射亚洲一区二区三区爱妻| 亚洲精品视频在线| 亚洲男人的天堂在线播放| 久久久久亚洲av无码尤物| 久久久亚洲精品国产| 亚洲国产精品第一区二区| 亚洲精品福利视频| 久久久久亚洲精品天堂| 久久精品亚洲中文字幕无码麻豆| 久久久久久亚洲AV无码专区| 亚洲性色成人av天堂| 亚洲免费二区三区| 国产99在线|亚洲| 亚洲精品成a人在线观看☆| 亚洲av无码一区二区三区四区| 亚洲国产高清国产拍精品| 色欲aⅴ亚洲情无码AV| 国产精品亚洲色图| 亚洲日韩国产成网在线观看| 久久精品国产亚洲Aⅴ香蕉| 久久久久亚洲AV无码专区桃色| 亚洲综合在线另类色区奇米| 国产精品亚洲精品日韩已满| 亚洲AV无码专区在线播放中文| 亚洲第一精品在线视频| 亚洲成无码人在线观看| 四虎必出精品亚洲高清| 亚洲妇女无套内射精| 亚洲av无码成人精品区在线播放 | 亚洲精品国自产拍在线观看| 亚洲中文字幕无码爆乳av中文| 国产成人综合亚洲AV第一页| 久久精品国产亚洲AV网站| 亚洲精品电影在线| 亚洲日本一线产区和二线产区对比| 亚洲aⅴ无码专区在线观看春色 | 亚洲精品一区二区三区四区乱码| 亚洲一区欧洲一区|