系統性能優化-2 CPU

系統性能優化-2 CPU

其實除了 CPU 的頻率,多核架構以及多 CPU 架構對系統運行的性能也是很大影響的,那么該如何充分利用 CPU 呢?

CPU 架構

首先介紹一下當前主流的 CPU 架構,現在的系統基本都是多 CPU,一個 CPU 處理器中一般有多個運行核心,我們把一個運行核心稱為一個物理核每個物理核都可以運行應用程序。每個物理核都擁有私有的一級緩存(Level 1 cache,簡稱 L1 cache),包括一級指令緩存和一級數據緩存,以及私有的二級緩存(Level 2 cache,簡稱 L2 cache)。同時,一個 CPU 上的所有物理核共享一個三級緩存。

image-20250617213848204

Centos 可以使用 lscpu 查看系統 CPU 信息

[root@VM-16-11-centos zwj]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                2
On-line CPU(s) list:   0,1
Thread(s) per core:    1
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 94
Model name:            Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz
Stepping:              3
CPU MHz:               2394.364
BogoMIPS:              4788.72
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
L3 cache:              28160K
NUMA node0 CPU(s):     0,1

程序在執行時,會先將內存中的數據載入三級緩存,再進入每顆核心獨有的二級緩存,最后進入最快的一級緩存,之后才會被 CPU 使用。

緩存比內存的訪問速度要快很多,訪問內存要100個時鐘周期以上,一級緩存只需要4~5個時鐘周期,二級緩存大約12個時鐘周期,三級緩存大約30個時鐘周期。因此如果 CPU 所要操作的數據可以命中緩存,會帶來一定的性能提升。

NUMA 架構

一個 CPU 的結構我們清楚了,但現在的系統基本都是多 CPU(也稱為多 CPU Socket),CPU 之間通過總線連接,如下圖所示:

image-20250617214720473

在多 CPU 架構上,應用程序可以在不同的 CPU 上執行,如果應用程序先在一個 Socket 上運行,并且把數據保存到了內存,然后被調度到另一個 Socket 上運行,此時,應用程序再進行內存訪問時,就需要訪問之前 Socket 上連接的內存,這種訪問屬于遠端內存訪問。和訪問 Socket 直接連接的內存相比,遠端內存訪問會增加應用程序的延遲。

在多 CPU 架構下,一個應用程序訪問所在 Socket 的本地內存和訪問遠端內存的延遲并不一致,所以,我們也把這個架構稱為非統一內存訪問架構(Non-Uniform Memory Access,NUMA 架構)

所以 CPU 架構對應用程序的運行主要有以下影響:

  • cpu 緩存訪問速度遠遠大于內存,因此盡量緩存命中,多利用緩存
  • NUMA 架構可能會出現遠端內存訪問的情況,這會直接增加應用程序的執行時間

提升緩存命中率

Centos 運行 lscpu

[root@VM-16-11-centos zwj]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
L3 cache:              28160K
NUMA node0 CPU(s):     0,1

可以看到 L1 cache 并不是單獨的,而是分為 L1d cache 和 L1i cache,也就是 數據緩存 和 指令緩存,因此提高緩存命中率也需要分別考慮

數據緩存

思考這樣一個場景,有一個二維數組需要進行一次遍歷

int arr[10][10];for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; i++) {printf("%d", arr[i][j])}
}
int arr[10][10];for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; i++) {printf("%d", arr[j][i])}
}

不要思考這個場景是否合理,比如需要遍歷一個數組把所有值加入到一個 set 中,思考這兩種方式的執行速度,其實方式1是遠優于方式2的(如果是 Python,會由于數組的設計效果沒那么明顯)。

原因是 CPU 其實有 Cache Line 的概念,CPU 在讀取數據時會一次性讀取 Cache Line 大小的數據到緩存中,而我們又知道數組在內存中是緊密排放的

arr[0][0] arr[0][1] arr[0][2]
arr[1][0]    
arr[2][0]    

如果按照第一種方式遍歷,就可以利用 CPU 緩存加快訪問

Linux 可以通過 cat /sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size 查看 Cache Line 大小

[root@VM-16-11-centos zwj]# cat /sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size 
64

Cache Line 在 nginx、redis 的設計中都有所體現:

  • nginx 使用哈希表存放域名、http頭部信息,哈希表里桶的大小如 server_names_hash_bucket_size,它默認就等于 CPU Cache Line 的值。由于所存放的字符串長度不能大于桶的大小,所以當需要存放更長的字符串時,就需要修改桶大小,但 Nginx 官網上明確建議它應該是 CPU Cache Line 的整數倍。
  • redis 的 sds 中,embstr 的 44 字節,其實也是 CPU Cache Line 的體現,當 robj + 字符串 + ‘\0’ 的長度不超過 64 時,此時編碼就是 embstr,在讀取到 robj 時就直接取到了字符串數據,無需再次訪問內存。

執行 perf stat 可以統計出進程運行時的系統信息(通過 -e 選項指定要統計的事件,如果要查看三級緩存總的命中率,可以指定緩存未命中 cache-misses 事件,以及讀取緩存次數 cache-references 事件,兩者相除就是緩存的未命中率,用 1 相減就是命中率。類似的,通過 L1-dcache-load-misses 和 L1-dcache-loads 可以得到 L1 緩存的命中率)

指令緩存

上面只是介紹了提高數據緩存的命中率,還有指令緩存的命中率

假如有一個數組,里面是一些 0~255 的數字,需要找出其中 < 128 的置為 0 并進行排序,方法1是先找到對應數據并置為0再排序,方法2是先排序再置為0。

for(i = 0; i < N; i++) {if (array [i] < 128) array[i] = 0;
}
sort(array, array + N);
sort(array, array + N);
for(i = 0; i < N; i++) {if (array [i] < 128) array[i] = 0;
}

先排序的方法速度其實是要更快的,原因是因為循環中有大量的 if 條件分支,而 CPU含有分支預測器。當代碼中出現 if、switch 等語句時,意味著此時至少可以選擇跳轉到兩段不同的指令去執行。如果分支預測器可以預測接下來要在哪段代碼執行(比如 if 還是 else 中的指令),就可以提前把這些指令放在緩存中,CPU 執行時就會很快。當數組中的元素完全隨機時,分支預測器無法有效工作,而當 array 數組有序時,分支預測器會動態地根據歷史命中數據對未來進行預測,命中率就會非常高

綁核

多 CPU 和多核心是不可避免的,為了緩解 NUMA 及應用程序重新調度后需要再次加載數據到 CPU 緩存的問題,操作系統提供了綁核指令,ls cpu 指令可以查看每個 CPU 對應的核心編號,可以使用 taskset 命令行指令在啟動時將應用程序與 CPU 進行綁定,也可以使用不同語言的 API (如sched_setaffinity)通過系統調用在程序代碼中設置進程的 CPU 親和性。此外,Perf 工具也提供了 cpu-migrations 事件,它可以顯示進程從不同的 CPU 核心上遷移的次數。

綁核是把雙刃劍,如果你的程序有很多的后臺線程,例如 redis 需要子線程生成 rdb、aof 重寫、刪除過期 key,就會導致子進程、后臺線程和主線程競爭 CPU 資源,一旦子進程或后臺線程占用 CPU 時,主線程就會被阻塞,導致 Redis 請求延遲增加。當然也有緩解的辦法,比如讓程序綁定一個具有多個邏輯核心的核,可以在一定程度上緩解 CPU 資源競爭。

不過 Redis 6 好像已經提供了支持 CPU 核綁定的配置操作了~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84307.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84307.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84307.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Docker Pull 相關配置指南

在Docker環境中&#xff0c;docker pull命令用于從Docker鏡像倉庫拉取鏡像。為了確保Docker鏡像能夠快速、穩定地拉取&#xff0c;配置 docker pull相關的設置是非常重要的。本文將詳細介紹如何配置Docker以優化 docker pull操作&#xff0c;涵蓋鏡像源配置、登錄私有倉庫、網絡…

Python的Matplotlib庫:從入門到精通的數據可視化實戰指南

&#x1f49d;&#x1f49d;&#x1f49d;歡迎蒞臨我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 持續學習&#xff0c;不斷…

CentOS查日志

在 CentOS 系統中&#xff0c;查看日志是系統維護和故障排查的重要技能。以下是常用的日志查看方法和工具&#xff1a; 1. 基本日志位置 CentOS 使用systemd管理服務&#xff0c;主要日志存儲在&#xff1a; /var/log/messages&#xff1a;系統主日志/var/log/secure&#x…

Linux運維新人自用筆記(用虛擬機Ubuntu部署lamp環境,搭建WordPress博客)

內容全為個人理解和自查資料梳理&#xff0c;歡迎各位大神指點&#xff01; 每天學習較為零散。 day20 一、./configure 腳本命令 ./configure 是 Unix/Linux 系統中用于配置軟件源代碼的腳本命令&#xff0c;通常用于為后續的 make 和 make install 準備編譯環境。 選項作…

JetBrains 2025 全家桶 包含 IDEA、WebStorm、DataGrip、Pycharm、CLion、GoLand、PhpStorm

JetBrains 2025 全家桶 11合1 包含&#xff1a;IDEA、WebStorm、DataSpell、DataGrip、Pycharm、RustRover、CLion、Rider、PhpStorm、RubyMine、GoLand。 原文地址&#xff1a;JetBrains 2025 全家桶 11合1 含 IDEA、PyCharm、DataGrip、WebStrom、GoLand、CLion、PhpStorm、D…

【一手實測】字節豆包 1.6 + Trae + 火山 MCP + FaaS:AI云原生 Agent 開發部署全流程體驗!

原創 Aitrainee AI進修生 2025年06月13日 16:42 湖南 標題已修改 緣起 —— 火山引擎在 2025 原動力大會上&#xff0c;也端出了自家的豆包大模型&#xff1a;Doubao-Seed-1.6 系列。 這三兄弟都支持文本、圖片、視頻輸入&#xff0c;都帶著 256K 的長上下文。 Doubao-Seed-…

Vulkan學習筆記8—頂點輸入描述與頂點緩沖

一、著色器代碼更新及構建時自動編譯著色器腳本 用內存中的頂點緩沖區替換頂點著色器中硬編碼的頂點數據 之前的頂點著色器&#xff1a; #version 450layout(location 0) out vec3 fragColor;// 頂點數據硬編碼 vec2 positions[3] vec2[](vec2(0.0, -0.5),vec2(0.5, 0.5),…

Day04_數據結構(棧鏈棧循環隊列)

01.棧 main.c #include "stack.h" int main() { stack_p S(stack_p)create_stack(); //1.入棧 …

PyTorch 的 CUDA GPU 支持 · 安裝五條鐵律(最新版 2025 修訂)(適用于所有用戶)

相關參考資料&#xff08;往期博客&#xff09;&#xff1a; 是否需要預先安裝 CUDA Toolkit&#xff1f;——按使用場景分級推薦及進階說明-CSDN博客 太方便&#xff0c;WIN系統CUDA12.4下使用conda便捷管理虛擬環境中的不同版本的CUDA、cuDNN、PyTorch-CSDN博客 好消息&#…

Django構建簡易視頻編輯管理系統

Django構建簡易視頻編輯管理系統 以下是基于Django構建簡易視頻編輯管理系統的可運行代碼框架&#xff0c;包含核心功能模塊和實現邏輯。該系統支持視頻上傳、基本剪輯操作和管理功能。 環境準備 安裝必要依賴包&#xff1a; pip install django pillow moviepy django-cri…

Java求職者面試題詳解:計算機網絡、操作系統、設計模式與數據結構

Java求職者面試題詳解&#xff1a;計算機網絡、操作系統、設計模式與數據結構 第一輪&#xff1a;基礎概念問題 1. 請解釋TCP和UDP的區別。 2. 什么是操作系統&#xff1f;它的主要功能是什么&#xff1f; 3. 請解釋設計模式中的單例模式&#xff0c;并給出一個實際應用的例…

【mysql】docker運行mysql8.0

背景 mariadb10.5.8報錯&#xff1a;Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘LIMIT ?’ at line 1 所以更換為mysql8.0.39試試 docker run啟動…

C#實現語音預處理:降噪/靜音檢測/自動增益

無論是在音視頻錄制系統&#xff0c;還是音視頻通話系統、或視頻會議系統中&#xff0c;對從麥克風采集到的說話的聲音數據進行預處理&#xff0c;都是是非常必要的。 語音數據預處理主要包括&#xff1a;??降噪&#xff08;Noise Reduction&#xff09;、靜音檢測&#xff0…

組合模式Composite Pattern

模式定義 又稱整體-部分模式 組合多個對象形成 樹形結構 以表示“整體-部分”的結構層次 組合模式對單個對象&#xff08;即葉子對象&#xff09;和組合對象&#xff08;即容器對象&#xff09;的使用具有一致性對象結構型模式 模式結構 Component&#xff1a;抽象構件Leaf&a…

商代大模型:智能重構下的文明曙光與青銅密碼

引言&#xff1a;技術奇點的歷史想象 在人類文明的長河中&#xff0c;技術的進步始終是推動社會變革的核心動力。從青銅冶煉到文字發明&#xff0c;從農業革命到工業革命&#xff0c;每一次技術飛躍都重塑了人類對世界的認知與生存方式。而如今&#xff0c;人工智能的崛起正以…

【Python】python系列之函數作用域

Python 系列文章學習記錄&#xff1a; Python系列之Windows環境安裝配置_開著拖拉機回家的博客-CSDN博客 Python系列之變量和運算符_開著拖拉機回家的博客-CSDN博客 Python系列之判斷和循環_開著拖拉機回家的博客-CSDN博客 Python系列之字符串和列表_開著拖拉機回家的博客…

Unity UI 核心類解析之Graphic

&#x1f9f1; Unity UI 核心類解析&#xff1a;Graphic 類詳解 一、什么是 Graphic&#xff1f; 在 Unity 的 UI 系統中&#xff0c;Graphic 是一個抽象基類&#xff0c;繼承自 UIBehaviour 并實現了 ICanvasElement 接口。它是所有可以被繪制到屏幕上的 UI 元素的基礎類。 …

【Elasticsearch】文檔遷移(Reindex)

文檔遷移 1.為什么要進行 reindex 操作2.Reindex 操作的本質3.實際案例3.1 同集群索引之間的全量數據遷移3.2 同集群索引之間基于特定條件的數據遷移3.2.1 源索引設置檢索條件3.2.2 基于 script 腳本的索引遷移3.2.3 基于預處理管道的數據遷移 3.3 不同集群之間的索引遷移3.4 查…

WordPress 區塊版面配置指南

WordPress 的區塊編輯器(Gutenberg)提供了靈活的版面配置選項&#xff0c;以下是主要配置方法&#xff1a; 基本區塊布局 添加區塊&#xff1a;點擊””按鈕或按”/”鍵快速插入區塊 常用內容區塊&#xff1a; 段落(Paragraph) 標題(Heading) 圖像(Image) 畫廊(Gallery)…

TensorFlow基礎之理解張量

2.理解張量 張量&#xff08;Tensors&#xff09;介紹 張量是物理和工程領域的基礎數學結構。但是過去張量很少在計算機科學里使用。它與離散數學和邏輯學有更多的聯系。隨著機器學習的出現&#xff0c;這種狀態開始顯著的改變&#xff0c;成為連續向量的計算基礎。現代機器學…