Linux內存管理章節十六:非均勻的內存訪問:深入Linux NUMA架構內存管理

引言

在傳統的SMP(對稱多處理)系統中,所有CPU核心通過一條共享總線訪問同一塊內存,所有內存訪問延遲是均勻的(UMA)。然而,隨著CPU核心數量的增加,共享總線成為了巨大的性能和 scalability 瓶頸。為了解決這個問題,NUMA(Non-Uniform Memory Access,非統一內存訪問) 架構應運而生。它帶來了更高的可擴展性,但也引入了新的復雜性:內存訪問速度取決于內存相對于執行CPU的位置。Linux內核必須感知并優化這種架構差異,否則性能將急劇下降。本文將解析NUMA的特點、內核的親和性調度策略以及跨節點訪問的優化手段。

一、 NUMA架構特點:距離產生延遲

NUMA架構的核心思想是將大量處理器分組,每個組成為一個節點(Node)。每個節點包含:

  • 一組CPU核心(通常是一個物理CPU插槽或多個核心的集合)
  • 一片本地內存(Local Memory)
  • 一個內存控制器集成在節點內

節點之間通過高速互連(如Intel的QPI、AMD的Infinity Fabric)連接。

關鍵特性:
  1. 訪問延遲不對稱

    • 本地訪問(Local Access):CPU訪問其所屬節點的本地內存,路徑最短,速度最快,延遲最低
    • 遠程訪問(Remote Access):CPU訪問其他節點的內存,必須通過節點間互連,速度較慢,延遲更高(通常比本地訪問慢1.5到2倍甚至更多)。
  2. 訪問帶寬不對稱

    • 每個節點的本地內存帶寬是獨享的。
    • 節點間互連的總帶寬是有限的,并且被所有節點共享。頻繁的遠程訪問會飽和互連帶寬,成為系統瓶頸。

對操作系統的影響:內核的內存分配策略不能再是“隨便找一塊空閑內存”。它必須盡量保證一個進程所使用的內存,其“歸屬”與運行該進程的CPU所在節點一致,即遵循節點親和性(Node Affinity),否則應用程序將遭受性能損失。

二、 節點親和性調度:將進程綁定在家門口

Linux內核提供了一套強大的機制來保證NUMA親和性,其目標是 “盡量讓任務在分配內存的同一個節點上運行,并盡量在任務運行的節點上為其分配內存”

1. 自動的NUMA平衡

現代Linux內核(CONFIG_NUMA_BALANCING)包含一個重要的后臺特性——自動NUMA平衡

  • 工作原理
    1. 跟蹤:內核周期性地標記進程的頁表項為“未訪問”(清除Accessed位)。
    2. 掃描:稍后再次檢查這些頁。如果發現一個頁被頻繁訪問,但其所在的NUMA節點與當前正在運行的CPU節點不一致,則判定該頁存在跨節點訪問
    3. 遷移:內核會嘗試執行兩種遷移:
      • 頁面遷移(Page Migration):將“熱”的內存頁遷移到當前運行的CPU的本地節點。
      • 任務遷移(Task Migration):將進程本身調度到內存頁所在的節點上運行。
  • 目標:通過動態遷移,減少遠程訪問次數,優化運行時性能。這對于不具備NUMA意識的應用程序尤其重要。
2. 手動調度策略與綁定

對于性能要求極高的應用(如數據庫、高性能計算),自動平衡可能不夠及時或會產生開銷。因此內核提供了手動控制的接口:

  • NUMA調度策略:通過set_mempolicy()系統調用或numactl命令,可以設置進程的內存分配策略。
    • MPOL_BIND:嚴格只在指定的一個或多個節點上分配內存。
    • MPOL_PREFERRED:優先從首選節點分配,失敗時再從其他節點分配。
    • MPOL_INTERLEAVE:在指定的多個節點之間交錯分配內存頁,用于均勻分散內存帶寬壓力。
  • CPU親和性(Affinity):通過sched_setaffinity()系統調用或taskset命令,可以將進程或線程綁定(pinning) 到特定的CPU核心上運行。
  • 聯合使用:最優策略通常是將進程綁定到一組核心,并設置其內存分配策略與這些核心所在的NUMA節點一致
# 使用 numactl 命令啟動一個程序,將其CPU和內存都限制在Node 0
numactl --cpunodebind=0 --membind=0 ./my_app# 使用 taskset 將進程綁定到特定CPU,再通過 numactl 設置內存策略
taskset -c 0-7 numactl --membind=0 ./my_app

三、 跨節點內存訪問優化:無法避免時的補救措施

盡管有親和性策略,但某些場景下跨節點訪問仍無法避免(例如,一個節點內存不足)。內核為此提供了多種優化機制。

1. 每節點伙伴分配器

內核并非運行一個全局的伙伴系統。在NUMA系統中,每個節點(Node)都擁有自己獨立的struct zone和伙伴分配器(Buddy Allocator)

  • 當在一個節點上請求分配內存時,分配器會首先嘗試從當前節點的本地內存中分配。
  • 只有當本地節點內存不足時,才會根據策略 fallback 到其他節點。
  • 這從分配源頭就最大限度地保證了內存的本地性。
2. SLAB分配器的每節點緩存

SLAB分配器同樣支持NUMA優化。它為每個CPU每個節點都創建了緩存。

  • kmalloc()等函數在分配內存時,會優先從當前CPU所在節點的緩存中獲取對象。
  • 這確保了被頻繁分配和釋放的小對象具有極好的訪問局部性。
3. 回退(Fallback)列表

每個NUMA節點都維護一個內存分配回退列表。當本地節點無法滿足分配請求時,內核會按照此列表的順序去嘗試其他節點。列表的順序通常由節點間的距離(Distance) 決定,優先選擇更“近”(訪問延遲更低)的節點。

4. 負載均衡與Interleave

對于需要巨大內存帶寬的應用,如果所有內存都集中在一個節點,其本地內存帶寬可能成為瓶頸。

  • Interleave策略:內核的MPOL_INTERLEAVE策略或硬件自帶的內存交錯功能,可以將連續的內存頁輪流分配到多個節點上。
  • 效果:這允許應用程序同時利用多個節點的內存控制器和帶寬,從而聚合出比單個節點更高的總帶寬。這對于大規模流式處理等場景非常有效,但代價是失去了局部性,所有訪問都變成了“遠程”。

總結

NUMA架構是高性能計算的基石,但也帶來了管理的復雜性。Linux內核通過一套組合策略來應對:

  1. 感知(Awareness):內核清晰地了解系統的NUMA拓撲結構,包括節點、CPU和內存的歸屬關系以及節點間的距離。
  2. 親和(Affinity):通過自動平衡手動綁定策略,極力保證任務在其內存所在的節點上運行,最大化本地訪問比例。
  3. 優化(Optimization):在架構上采用每節點分配器,在無法避免遠程訪問時,通過回退列表選擇最近的節點,或在需要帶寬時采用交錯分配

對于系統管理員和開發者而言,理解NUMA意味著:

  • 使用numastat命令監控各節點的內存分配和跨節點訪問(numa_miss)情況。
  • 使用numactltaskset對關鍵應用進行精細化的資源調度的綁定。
  • 在編寫程序時,考慮數據局部性,避免線程在CPU間頻繁遷移而導致內存訪問模式惡化。

掌握NUMA內存管理,是從“讓程序能運行”到“讓程序在高端硬件上飛起來”的關鍵一步。

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

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

相關文章

【論文翻譯】Seg-Zero: Reasoning-Chain Guided Segmentation via Cognitive Reinforcement

0. 摘要Traditional methods for reasoning segmentation rely on supervised fine-tuning with categorical labels and simple descriptions, limiting its out-of-domain generalization and lacking explicit reasoning processes. To address these limitations, we propo…

Playwright MCP瀏覽器自動化教程

你是否曾厭倦在編程軟件和瀏覽器之間反復切換,只為了檢查AI生成的代碼能否正常運行?現在,有了Playwright MCP(Model Context Protocol),你可以直接讓AI自己操作瀏覽器,查看自己寫的代碼運行效果…

矩陣中遍歷某個點周圍的九個點

又是學習新知識的一天,以下為Java版本部分關鍵代碼int[] neighbors {0, 1, -1};int rows board.length;int cols board[0].length;int[][] copyBoard new int[rows][cols];for (int row 0; row < rows; row) {for (int col 0; col < cols; col) {int liveNeighbors…

單例模式:只有一個對象

目錄 什么是單例模式 能解決什么問題 使用場景 如何實現 __new__ 方法&#xff1a;經典又直接 裝飾器&#xff1a;不改類本身&#xff0c;也能單例 模塊本身就是單例 注意事項 總結 你有沒有過這樣的困擾&#xff1a; “為什么我明明只創建了一次數據庫連接&#xff0…

AI大模型學習(6)Yolo V8神經網絡的基礎應用

Yolo V8神經網絡的基礎應用2024-2025年最火的目標檢測神器&#xff0c;一篇文章讓你徹底搞懂&#xff01;&#x1f929;大家好呀&#xff01;今天我們要聊一聊計算機視覺領域的「明星模型」——YOLO神經網絡&#xff01;&#x1f3af; 如果你對「目標檢測」這個詞還比較陌生&am…

C++:imagehlp庫

imagehlp庫1. 簡介2. 主要函數與用途2.1PE 文件解析相關2.2 符號處理相關2.3 崩潰轉儲相關2.4 版本資源相關3. 使用示例3.1 解析內存地址對應的函數名和行號3.2 創建目錄使用示例1. 簡介 imagehlp 是 Windows 系統提供的一個圖像處理與調試輔助 API 庫&#xff08;Image Helpe…

如何在Anaconda中配置你的CUDA Pytorch cuNN環境(2025最新教程)

目錄 一、簡介 二、下載CUDA 三、下載Pytorch-GPU版本 四、下載CUDNN 五、總結 六、測試代碼 一、簡介 啥是Anaconda?啥是CUDA?啥是CUDNN&#xff1f;它們和Pytorch、GPU之間有啥關系? 怎么通俗解釋它們三者的用途和關系&#xff1f; 1.GPU(圖形處理單元&#xff09…

算法面試(1)-----目標檢測和圖像分類、語義分割的區別

操作系統&#xff1a;ubuntu22.04 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 目標檢測&#xff08;Object Detection&#xff09;、圖像分類&#xff08;Image Classification&#xff09;、語義分割&#xff08;Semantic Segmentation&#xff09; 是計算機視…

電腦散熱風扇有噪音怎么解決

一、初步檢查與清理斷電并拆機關閉電腦并拔掉電源&#xff0c;打開機箱側板&#xff08;筆記本需先拆除后蓋螺絲&#xff09;。操作前建議佩戴防靜電手環&#xff0c;避免靜電損壞硬件。清理風扇及散熱片灰塵使用壓縮空氣罐從風扇進風口吹走灰塵&#xff0c;或用軟毛刷輕輕刷去…

SeaweedFS深度解析(九):k8s環境使用helm部署Seaweedfs集群

上一篇&#xff1a;《SeaweedFS深度解析&#xff08;八&#xff09;&#xff1a;k8s環境使用Operator部署Seaweedfs集群》 鏈接: link #作者&#xff1a;閆乾苓 文章目錄k8s環境使用helm部署Seaweedfs集群準備鏡像seaweed-master-localpv-storageclass.yamlseaweed-volume-lo…

MATLAB繪制一個新穎的混沌圖像(新四翼混沌系統)

新四翼混沌系統:dx/dt a(y - x) yz dy/dt cx - y - xz dz/dt -bz xyMATLAB代碼:function plot_novel_chaotic_system() % 參數設置 a 10; b 8/3; c 28;% 初始條件 x0 [1, 1, 1];% 時間范圍 tspan [0 100];% 求解微分方程 [t, x] ode45((t, x) chaotic_system(t, x, …

金融數據---獲取股票日線數據

獲取股票日線的數據方式有很多&#xff0c;包括東方財富&#xff0c;同花順&#xff0c;tushare&#xff0c;這里我們就利用東方財富的數據&#xff0c;是免費的開源獲取&#xff0c;第一步先安裝akshare&#xff0c;pip安裝就可以py -m pip install akshareAkshare 股票數據獲…

Mac 真正多顯示器支持:TESmart USB-C KVM(搭載 DisplayLink 技術)如何實現

多顯示器已經不再是奢侈品&#xff0c;而是專業人士提升生產力的必需工具。無論是創意設計師、股票交易員還是軟件開發人員&#xff0c;多屏幕都能讓工作流程更高效、更有條理。 然而&#xff0c;Mac 用戶長期以來面臨一個主要障礙&#xff1a;macOS 原生不支持多流傳輸&#x…

【實時Linux實戰系列】靜態鏈接與libc選擇:musl vs glibc的時延權衡

背景與重要性 在實時系統開發中&#xff0c;選擇合適的C標準庫&#xff08;libc&#xff09;和鏈接方式對系統的啟動時間、線程性能和內存分配效率有著顯著影響。glibc和musl是兩種流行的C標準庫實現&#xff0c;它們在設計目標和性能表現上存在差異。通過對比這兩種libc在啟動…

Altium Designer(AD24)的三種文件組織形式,工程文件,自由文件與存盤文件

??《專欄目錄》 目錄 1,概述 2,工程文件 3,自由文件 4,存盤文件 5,文件轉換 5.1,工程文件于自由文件互轉換 5.2,工程文件于存盤文件互轉換 6,注意事項 1,概述 本文介紹Altium Designer 24軟件(后文簡稱AD24或軟件)的三種文件組織形式,工程文件,自由文件和存盤文…

Python+Selenium實現自動化測試

&#x1f345; 點擊文末小卡片 &#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快安裝selenium打開命令控制符輸入&#xff1a;pip install -U selenium火狐瀏覽器安裝firebug&#xff1a;www.firebug.com&#xff0c;調試所有網站語言&#xff0…

2024年CSP-X初賽真題及答案解析(6-10)

2024年CSP-X初賽真題及答案解析(6-10) 字符串abcabcabc有多少不同的非空子串?( )。 A. 24 B. 36 C. 45 D. 46 答案:A 解析: 長度 1: 3 個(a, b, c) 長度 2: 3 個(ab, bc, ca) 長度 3: 3 個(abc, bca, cab) 長度 4: 3 個(abca, bcab, cabc) 長度 5: 3 個(a…

緩存與數據庫一致性的4大坑及終極解決方案

緩存雪崩、擊穿、穿透全中招&#xff1f;別讓緩存與數據庫的“愛恨情仇”毀了你的系統&#xff01; 你有沒有經歷過這樣的深夜告警&#xff1a;Redis 響應延遲飆升&#xff0c;數據庫 CPU 直沖 100%&#xff0c;接口大面積超時&#xff1f;一查日志&#xff0c;發現大量請求繞過…

基于 Python charm 庫實現的一些 Pairing 密碼學算法

基于 Python charm 庫實現了一些 Pairing 密碼學算法&#xff0c;放在了 https://github.com/BatchClayderman/Cryptography-Schemes 里面。 在正確部署了 Python charm 庫后&#xff0c;所有的 Python 腳本都是獨立的&#xff0c;即該存儲庫中不存在一個腳本調用另一個腳本的…

用戶體驗五大要點:從問題到解決方案的完整指南

在互聯網產品設計和運營的過程中&#xff0c;用戶體驗&#xff08;User Experience&#xff0c;簡稱 UX&#xff09; 已經成為決定產品成敗的關鍵因素。一個功能再強大的產品&#xff0c;如果用戶用得不舒服、不信任&#xff0c;甚至覺得沒有價值&#xff0c;最終都會被拋棄。那…