1. 程式人生 > >Linux效能優化之CPU優化(一)

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使用狀態,在第一列顯示可執行程序數。如下所示:

1

2

3

4

[[email protected] ~]# 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的統計資訊。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

[[email protected] ~]# 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調優
    啟用睿頻

轉載:https://www.cnblogs.com/yangxiaoyi/p/7532920.html