系統效能調優:提升 CPU 快取的命中率

roc_guo發表於2021-07-27
導讀 如果 CPU 所要操作的資料在快取中,則直接讀取,這稱為快取命中。命中快取會帶來很大的效能提升,因此,我們的程式碼最佳化目標是提升 CPU 快取的命中率。

系統效能調優:提升 CPU 快取的命中率系統效能調優:提升 CPU 快取的命中率

支援超執行緒的numa架構

物理硬體視角,將多個CPU封裝在一起,這個封裝被稱為插槽Socket;Core是socket上獨立的硬體單元;透過intel的超執行緒HT技術進一步提升CPU的處理能力,OS看到的邏輯上的核Processor的數量。

每個硬體執行緒都可以按邏輯cpu定址,因此這個處理器看上去有八塊cpu。

系統效能調優:提升 CPU 快取的命中率系統效能調優:提升 CPU 快取的命中率

對於作業系統的視角:

  • CPU(s):8
  • NUMA node0 CPU(s):0,4
  • NUMA node1 CPU(s):1,5
  • NUMA node2 CPU(s):2,6
  • NUMA node3 CPU(s):3,7

系統效能調優:提升 CPU 快取的命中率系統效能調優:提升 CPU 快取的命中率

L1緩分成兩種,一種是指令快取,一種是資料快取。L2快取和L3快取不分指令和資料。L1和L2快取在第一個CPU核中,L3則是所有CPU核心共享的記憶體。L1、L2、L3的越離CPU近就越小,速度也越快,越離CPU遠,速度也越慢。再往後面就是記憶體,記憶體的後面就是硬碟。我們來看一些他們的速度:

  • L1 的存取速度:4 個CPU時鐘週期
  • L2 的存取速度:11 個CPU時鐘週期
  • L3 的存取速度:39 個CPU時鐘週期
  • RAM記憶體的存取速度 :107 個CPU時鐘週期

如果 CPU 所要操作的資料在快取中,則直接讀取,這稱為快取命中。命中快取會帶來很大的效能提升,因此,我們的程式碼最佳化目標是提升 CPU 快取的命中率。

在主流的伺服器上,一個 CPU 處理器會有 10 到 20 多個物理核。同時,為了提升伺服器的處理能力,伺服器上通常還會有多個 CPU 處理器(也稱為多 CPU Socket),每個處理器有自己的物理核(包括 L1、L2 快取),L3 快取,以及連線的記憶體,同時,不同處理器間透過匯流排連線。透過lscpu來看:

root@ubuntu:~# lscpu
Architecture:          x86_64
CPU(s):                32
Thread(s) per core:    1
Core(s) per socket:    8
Socket(s):             4
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              20480K
NUMA node0 CPU(s):     0-7
NUMA node1 CPU(s):     8-15
NUMA node2 CPU(s):     16-23
NUMA node3 CPU(s):     24-31

你可能注意到,三級快取要比一、二級快取大許多倍,這是因為當下的 CPU 都是多核心的,每個核心都有自己的一、二級快取,但三級快取卻是一顆 CPU 上所有核心共享的。

但是,有個地方需要你注意一下:如果應用程式先在一個 Socket 上執行,並且把資料儲存到了記憶體,然後被排程到另一個 Socket 上執行,此時,應用程式再進行記憶體訪問時,就需要訪問之前 Socket 上連線的記憶體,這種訪問屬於遠端記憶體訪問。和訪問 Socket 直接連線的記憶體相比,遠端記憶體訪問會增加應用程式的延遲。

常用效能監測工具

下,CPU與記憶體子系統效能調優的常用效能監測工具有top、perf、numactl這3個工具。1) top工具 top工具是最常用的 效能監測工具之一。透過top工具可以監視程式和系統整體效能。

  • top 檢視系統整體的資源使用情況
  • top後輸入1 檢視看每一個邏輯核cpu的資源使用情況
  • top -p $PID -H 檢視某個程式內所有檢查的CPU資源使用情況
  • top後輸入F,並選擇P選項 檢視執行緒執行過程中是否排程到其他cpu上執行,上下文切換過多時,需要注意。

2) perf工具 perf工具是非常強大的Linux效能分析工具,可以透過該工具獲得程式內的呼叫情況、資源消耗情況並查詢分析熱點函式。以 為例,使用如下 安裝perf工具:

  • perf top 檢視佔用 CPU 時鐘最多的函式或者指令,因此可以用來查詢熱點函式。
  • perf -g record -- sleep 1 -p $PID 記錄程式在1s內的系統呼叫。
  • perf -g latency --sort max 檢視上一步記錄的結果,以排程延遲排序。
  • perf report 檢視記錄

3) numactl工具 numactl工具可用於檢視當前伺服器的NUMA節點配置、狀態,可透過該工具將程式繫結到指定CPU核上,由指定CPU核來執行對應程式。以CentOS為例,使用如下 安裝numactl工具:

  • numactl -H 檢視當前伺服器的NUMA配置。
  • numastat 檢視當前的NUMA執行狀態。
最佳化方法

(1) NUMA最佳化,減少跨NUMA訪問記憶體 不同NUMA內的CPU核訪問同一個位置的記憶體,效能不同。記憶體訪問延時從高到低為:跨CPU>跨NUMA,不跨CPU>NUMA內。因此在應用程式執行時要儘可能地避免跨NUMA訪問記憶體,這可以透過設定執行緒的CPU親和性來實現。常用的修改方式有如下:(1)將裝置中斷繫結到特定CPU核上。可以透過如下命令繫結:

echo $cpuNumber > /proc/irq/$irq/smp_affinity_list
 例子:echo 0-4 > /proc/irq/78/smp_affinity_list
      echo 3,8 > /proc/irq/78/smp_affinity_list

(2)透過numactl啟動程式,如下面的啟動命令表示啟動程式./mongod,mongo就只能在CPU core 0到core7執行(-C控制)。

numactl -C 0-7 ./mongod

(3)可以使用 taskset 命令把一個程式繫結在一個核上執行。

taskset -c 0 ./redis-server

(4)在C/C++程式碼中透過sched_setaffinity函式來設定執行緒親和性。(5)很多開源軟體已經支援在自帶的配置檔案中修改執行緒的親和性,例如Nginx可以修改nginx.conf檔案中worker_cpu_affinity引數來設定Nginx執行緒親和性。

綁核注意事項

在 CPU 的 NUMA 架構下,對 CPU 核的編號規則,並不是先把一個 CPU Socket 中的所有邏輯核編完,再對下一個 CPU Socket 中的邏輯核編碼,而是先給每個 CPU Socket 中每個物理核的第一個邏輯核依次編號,再給每個 CPU Socket 中的物理核的第二個邏輯核依次編號。

系統效能調優:提升 CPU 快取的命中率系統效能調優:提升 CPU 快取的命中率

注意的是在多個程式要進行親和性綁核的,你一定要注意 NUMA 架構下 CPU 核的編號方法,這樣才不會綁錯核。

原文來自

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2783920/,如需轉載,請註明出處,否則將追究法律責任。

相關文章