Linux性能優化之CPU優化(一)


前言

何為性能優化?個人認為,性能優化是為了提高應用程序或系統能力為目的。那么如何才能實現對應用程序的性能調優呢?這里很設計到很多的內容,包括Linux內核、CPU架構以及Linux內核對資源的分配以及管理,了解進程的創建過程等。這方面由於篇幅較多,所以我的文章就不過多介紹。接下來的幾篇文章中,都是講解如何發現應用程序故障根源為目標講解,這也是每一個系統工程師應該具備的能力。廢話不多說,我直接進入主題。

常用術語

  延時:延時是描述操作之后用來等待返回結果的時間。在某些情況下,它可以指的是整個操作時間,等同於響應時間。

  IOPS:每秒發生的輸入/輸出操作的次數,是數據傳輸的一個度量方法。對於磁盤的讀寫,IOPS指的是每秒讀寫的次數。

  響應時間:一般操作完成的時間。包括用於等待和服務的時間,也包括用來返回結果的時間。

  使用率:對於服務所請求的資源,使用率描述在所給定時間區間內資源的繁忙程度。對於春初資源來說,使用率指的就是所消耗的存儲容量。

  飽和度:指的就是某一資源無法滿足服務的排隊工作量。

  吞吐量:評價工作秩序的速率,尤其是在數據傳輸方面,這個屬於用於數據傳輸速度(字節/秒和比特/秒)。在某些情況下,吞吐量指的是操作的速度。

Linux內核功能

  CPU調度級別:各種先進的CPU調度算法,非一直存儲訪問架構(NUMA);

  I/O調度界別:I/O調度算法,包括deadline/anticipatory和完全公平隊列(CFQ);

  TCP網絡阻塞:TCP擁堵算法,允許按需選擇;

常見問題

進程、線程和任務之間的區別是什么?

  進程通常定義為程序的執行。用以執行用戶級別程序的環境。它包括內存地址空間、文件描述符、線程棧和寄存器。
  線程是某一進程中單獨運行的程序。也就是說線程在進程之中。
  任務是程序完成的某一活動,可以使一個進程,也可以是一個線程。

參考連接:http://blog.chinaunix.net/uid-25100840-id-271078.html

什么是上下文切換?

  執行一段程序代碼,實現一個功能的過程介紹,當得到CPU的時候,相關的資源必須也已經就位,就是顯卡、內存、GPS等,然后CPU開始執行。這里除了CPU以外所有的就構成了這個程序的執行環境,也就是我們所定義的程序上下文。當這個程序執行完或者分配給他的CPU執行時間用完了,那它就要被切換出去,等待下一次CPU的臨幸。在被切換出去的最后一步工作就是保存程序上下文,因為這個是下次他被CPU臨幸的運行環境,必須保存。

I/O密集型和CPU密集型工作負載之間的區別?

  I/O密集型指的是系統的CPU耗能相對硬盤/內存的耗能能要好很多,此時,系統運作,大部分的狀況是 CPU 在等 I/O(硬盤/內存)的讀/寫,此時CPU負載不高。CPU密集型指的是系統的硬盤/內存耗能相對CPU的耗能要好很多,此時,系統運作,大部分的狀況是 CPU負載 100%,CPU 要讀/寫 I/O (硬盤/內存),I/O在很短的時間就可以完成,而CPU還有許多運算要處理,CPU負載很高。一般而言CPU占用率相當高,大部份時間用來做計算、邏輯判斷等CPU動作的程序。

應用程序性能技術

1.選擇I/O尺寸
  執行I/O的開銷包括初始化緩沖區、系統調用、上下文切換、分配內核元數據、檢查進程權限和限制、映射地址到設備、執行內核和驅動代碼來執行I/O,以及在最后釋放元數據和緩沖區。增加I/O尺寸是應用程序提高吞吐量的常用策略。
2.緩存
  操作系統用緩存提高文件系統的讀性能和內存的分配性能,應用程序使用緩存也處於類似的原因。將經常執行的操作結果保存在本地緩存中以備后用,而非總是執行開銷較高的操作。
3.緩沖區
  為了提高寫操作性能,數據在送入下一層級之前會合並並放在緩沖區中。這樣會增加寫延時,因為第一次寫入緩沖區后,在發送之前,還要等待后續的寫入。
4. 並發和並行
  並行:裝在和開始執行多個可運行程序的能力(比如,同時接電話和吃飯)。為了利用多核處理器系統的優勢,應用程序需要在同一時間運行在多顆CPU上,這種方式稱為並行。應用程序通過多進程或多線程實現。
  並發:有處理多個任務的能力,不一定要同時。比如,接完電話在去吃飯,存在資源搶占;
  同步原語:同步原語監管內存的訪問,當不允許訪問時,就會引起等待時間(延時)。常見三種類型:
  mutex鎖:只有鎖持有者才能操作,其他線程會阻塞並等待CPU;
  自旋鎖:自旋鎖允許鎖持有者操作,其他的需要自旋鎖的線程會在CPU上循環自選,檢查鎖是否被釋放。雖然這樣可以提供低延時的訪問,被阻塞的線程不會離開CPU,時刻准備着運行知道鎖可用,但是線程自旋、等待也是對CPU資源的浪費。
  讀寫鎖:讀/寫鎖通過允許多個讀者或者只允許一個寫者而沒有讀者,來保證數據的完整性。
  自適應自旋鎖:低延遲的訪問而不浪費CPU資源,是mutex鎖和自旋鎖的混合。
5.綁定CPU

關於CPU性能分析

uptime:
  系統負載,通過匯總正在運行的線程數和正在排隊等待運行的線程數計算得出。分別反映1/5/15分鍾以內的負載。現在的平均負載不僅用來表示CPU余量或者飽和度,也不能單從這個值推斷出CPU或者磁盤負載。

vmstat:
  虛擬內存統計信息命令。最后幾列打印系統全局范圍內的CPU使用狀態,在第一列顯示可運行進程數。如下所示:

[root@zbredis-30104 ~]# vmstat 
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r  b   swpd   free   buff   cache   si   so    bi    bo   in   cs us sy id  wa  st
0  0   0    14834208 158384 936512  0     0     0     0    1   3   0  0 100  0  0

提示:

  r: 運行隊列長度和正在運行的線程數;

  b: 表示阻塞的進程數;

  swpd: 虛擬內存已使用的大小,如果大於0,表示你的機器物理內存不足了,如果不是程序內存泄露的原因,那么你該升級內存了或者把耗內存的任務遷移到其他機器;

  si: 每秒從磁盤讀入虛擬內存的大小,如果這個值大於0,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。我的機器內存充裕,一切正常。

  so: 每秒虛擬內存寫入磁盤的大小,如果這個值大於0,同上;

  bi: 塊設備每秒接收的塊數量,這里的塊設備是指系統上所有的磁盤和其他塊設備,默認塊大小是1024byte,我本機上沒什么IO操作,所以一直是0,但是我曾在處理拷貝大量數據(2-3T)的機器上看過可以達到140000/s,磁盤寫入速度差不多140M每秒;

  bo: 塊設備每秒發送的塊數量,例如我們讀取文件,bo就要大於0。bi和bo一般都要接近0,不然就是IO過於頻繁,需要調整;

  in: 每秒CPU的中斷次數,包括時間中斷;

  cs:  每秒上下文切換次數,例如我們調用系統函數,就要進行上下文切換,線程的切換,也要進程上下文切換,這個值要越小越好,太大了,要考慮調低線程或者進程的數目,例如在apache和nginx這種web服務器中,我們一般做性能測試時會進行幾千並發甚至幾萬並發的測試,選擇web服務器的進程可以由進程或者線程的峰值一直下調,壓測,直到cs到一個比較小的值,這個進程和線程數就是比較合適的值了。系統調用也是,每次調用系統函數,我們的代碼就會進入內核空間,導致上下文切換,這個是很耗資源,也要盡量避免頻繁調用系統函數。上下文切換次數過多表示你的CPU大部分浪費在上下文切換,導致CPU干正經事的時間少了,CPU沒有充分利用,是不可取的。

  st: cpu在虛擬化環境上在其他租戶上的開銷;

mpstat:
  多處理器統計信息工具,能夠報告每個CPU的統計信息。

[root@zbredis-30104 ~]# mpstat -P ALL 1
Linux 2.6.32-573.el6.x86_64 (zbredis-30104) 	09/14/2017 	_x86_64_	(12 CPU)

03:14:03 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
03:14:04 PM  all    0.00    0.00    0.08    0.00    0.00    0.00    0.00    0.00   99.92
03:14:04 PM    0    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    1    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    2    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    3    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    4    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    5    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    6    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    7    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    8    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM    9    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM   10    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
03:14:04 PM   11    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00

提示:

  irq: 硬件中斷CPU用量;

  sofr: 軟件中斷CPU用量;
  steal: 耗費在服務其他租戶的時間;
  guest: 花在訪客虛擬機的時間;

  重要關注列有%user/%sys/%idle。顯示了每個CPU的用量以及用戶態和內核態的時間比例。可以根據這些值查看那些跑到100%使用率(%user + %sys)的CPU,而其他CPU並未跑滿可能是由單線程應用程序的負載或者設備中斷映射造成。

sar:

  系統活動報告器。用來觀察當前的活動,以及配置用以歸檔和報告歷史統計信息。基本上所有資源使用的信息,它都能夠查看到。具體的參數說明如下所示:

  -A: 所有報告的總和,類似"-bBdqrRSuvwWy -I SUM -I XALL -n ALL -u ALL -P ALL"參數一起使用;
  -b: 顯示I/O和傳輸速率的統計信息;
  -B:顯示分頁狀態;
  -d:硬盤使用報告;
  -r:內存和交換空間的使用統計;
  -g:串口I/O的情況;
  -b:緩沖區使用情況;
  -a:文件讀寫情況;
  -c:系統調用情況;
  -n: 統計網絡信息;
  -q:報告隊列長度和系統平均負載;
  -R:進程的活動情況;
  -y:終端設備活動情況;
  -w:系統交換活動;
  -x { pid | SELF | ALL }:報告指定進程ID的統計信息,SELF關鍵字是sar進程本身的統計,ALL關鍵字是所有系統進程的統計;

常用參數組合:

  查看CPU:

  整體CPU統計— sar -u 3 2,表示采樣時間為3秒,采樣次數為2次;
  各個CPU統計— sar -P ALL 1 1,表示采樣時間為1秒,次數為1次;

    1. 若 %iowait 的值過高,表示硬盤存在I/O瓶頸;
    2. 若 %idle 的值高但系統響應慢時,有可能是 CPU 等待分配內存,此時應加大內存容量;
    3. 若 %idle 的值持續低於1,則系統的 CPU 處理能力相對較低,表明系統中最需要解決的資源是 CPU;

  查看內存:

  查看內存使用情況 - sar -r 1 2

    kbcommit:保證當前系統所需要的內存,即為了確保不溢出而需要的內存(RAM+swap);
    %commit:這個值是kbcommit與內存總量(包括swap)的一個百分比;

  pidstat:主要用於監控全部或指定進程占用系統資源的情況,如CPU,內存、設備IO、任務切換、線程等。

  cpu使用情況統計
    執行 "pidstat -u" 與單獨執行 "pidstat"
  內存使用情況統計
    pidstat -r -p PID 1

    minflt/s: 每秒次缺頁錯誤次數(minor page faults),次缺頁錯誤次數意即虛擬內存地址映射成物理內存地址產生的page fault次數;
    majflt/s: 每秒主缺頁錯誤次數(major page faults),當虛擬內存地址映射成物理內存地址時,相應的page在swap中,這樣的page fault為major page fault,一般在內存使用緊張時產生;
  IO情況統計
    pidstat -d 1 2

關於CPU方面的優化

  1.編譯器優化
  2.調度優先級和調度類(設置nice值)
    例如,nice -n 19 command
    renice 更改已經運行進程的優先級;
    chrt 命令顯示並直接修改優先級和調度策略;
  3.進程綁定(一個進程可以綁定在一個或者多個CPU上)
    例如,taskset -pc 0-3 10790

  4.獨占CPU
  5.BIOS調優
    啟用睿頻

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM