【計算機體系結構】NUMA架構詳解

基本概念

SMP VS. AMP

那麼兩者之間的主要區別是什麼呢? 總結下來有這麼幾點,

  1. SMP的多個處理器都是同構的,使用相同架構的CPU;而AMP的多個處理器則可能是異構的。
  2. SMP的多個處理器共享同一內存地址空間;而AMP的每個處理器則擁有自己獨立的地址空間。
  3. SMP的多個處理器操通常共享一個操作系統的實例;而AMP的每個處理器可以有或者沒有運行操作系統, 運行操作系統的CPU也是在運行多個獨立的實例。
  4. SMP的多處理器之間可以通過共享內存來協同通信;而AMP則需要提供一種處理器間的通信機制。

SMP和AMP的深入介紹很多經典文章書籍可參考,此處不再贅述。現今主流的x86多處理器服務器都是SMP架構的, 而很多嵌入式系統則是AMP架構的。

NUMA VS. UMA

NUMA(Non-Uniform Memory Access) 非均勻內存訪問架構是指多處理器系統中,內存的訪問時間是依賴於處理器和內存之間的相對位置的。 這種設計裏存在和處理器相對近的內存,通常被稱作本地內存;還有和處理器相對遠的內存, 通常被稱爲非本地內存。

UMA(Uniform Memory Access) 均勻內存訪問架構則是與NUMA相反,所以處理器對共享內存的訪問距離和時間是相同的。

由此可知,不論是NUMA還是UMA都是SMP架構的一種設計和實現上的選擇。

閱讀文檔時,也常常能看到ccNUMA(Cache Coherent NUMA),即緩存一致性NUMA架構。 這種架構主要是在NUMA架構之上保證了多處理器之間的緩存一致性。降低了系統程序的編寫難度。

x86多處理器發展歷史上,早期的多核和多處理器系統都是UMA架構的。這種架構下, 多個CPU通過同一個北橋(North Bridge)芯片與內存鏈接。北橋芯片裏集成了內存控制器(Memory Controller),

下圖是一個典型的早期 x86 UMA 系統,四路處理器通過 FSB (前端系統總線, Front Side Bus) 和主板上的內存控制器芯片 (MCH, Memory Controller Hub) 相連,DRAM 是以 UMA 方式組織的,延遲並無訪問差異。

x86 UMA

x86 UMA

 

注:

在 UMA 架構下,CPU 和內存控制器之間的前端總線 (FSB) 在系統 CPU 數量不斷增加的前提下, 成爲了系統性能的瓶頸。因此,AMD 在引入 64 位 x86 架構時,實現了 NUMA 架構。之後, Intel 也推出了 x64 的 Nehalem 架構,x86 終於全面進入到 NUMA 時代。x86 NUMA 目前的實現屬於 ccNUMA。

從 Nehalem 架構開始,x86 開始轉向 NUMA 架構,內存控制器芯片被集成到處理器內部,多個處理器通過 QPI 鏈路相連,從此 DRAM 有了遠近之分。 而 Sandybridge 架構則更近一步,將片外的 IOH 芯片也集成到了處理器內部,至此,內存控制器和 PCIe Root Complex 全部在處理器內部了。 下圖就是一個典型的 x86 的 NUMA 架構:

        ​​​​​​​    ​​​​​​​    ​​​​​​​    ​​​​​​​    

x86 典型 NUMA 架構

 

NUMA Hierarchy

NUMA Node 內部

一個NUMA Node內部是由一個物理CPU和它所有的本地內存(Local Memory)組成的。廣義得講, 一個NUMA Node內部還包含本地IO資源,對大多數Intel x86 NUMA平臺來說,主要是PCIe總線資源。 ACPI規範就是這麼抽象一個NUMA Node的。

物理 CPU

一個CPU Socket裏可以由多個CPU Core和一個Uncore部分組成。每個CPU Core內部又可以由兩個CPU Thread組成。 每個CPU thread都是一個操作系統可見的邏輯CPU。對大多數操作系統來說,一個八核HT打開的CPU會被識別爲16個CPU。 下面就說一說這裏面相關的概念,

  • Socket

    一個Socket對應一個物理CPU。 這個詞大概是從CPU在主板上的物理連接方式上來的,可以理解爲 Socket 就是主板上的 CPU 插槽。處理器通過主板的Socket來插到主板上。 尤其是有了多核(Multi-core)系統以後,Multi-socket系統被用來指明系統到底存在多少個物理CPU。

  • Node

    NUMA體系結構中多了Node的概念,這個概念其實是用來解決core的分組的問題。每個node有自己的內部CPU,總線和內存,同時還可以訪問其他node內的內存,NUMA的最大的優勢就是可以方便的增加CPU的數量。通常一個 Socket 有一個 Node,也有可能一個 Socket 有多個 Node。

  • Core

    CPU的運算核心。 x86的核包含了CPU運算的基本部件,如邏輯運算單元(ALU), 浮點運算單元(FPU), L1和L2緩存。 一個Socket裏可以有多個Core。如今的多核時代,即使是Single Socket的系統, 也是邏輯上的SMP系統。但是,一個物理CPU的系統不存在非本地內存,因此相當於UMA系統。

  • Uncore

    Intel x86物理CPU裏沒有放在Core裏的部件都被叫做Uncore。Uncore裏集成了過去x86 UMA架構時代北橋芯片的基本功能。 在Nehalem時代,內存控制器被集成到CPU裏,叫做iMC(Integrated Memory Controller)。 而PCIe Root Complex還做爲獨立部件在IO Hub芯片裏。到了SandyBridge時代,PCIe Root Complex也被集成到了CPU裏。 現今的Uncore部分,除了iMC,PCIe Root Complex,還有QPI(QuickPath Interconnect)控制器, L3緩存,CBox(負責緩存一致性),及其它外設控制器。

  • Threads

    這裏特指CPU的多線程技術。在Intel x86架構下,CPU的多線程技術被稱作超線程(Hyper-Threading)技術。 Intel的超線程技術在一個處理器Core內部引入了額外的硬件設計模擬了兩個邏輯處理器(Logical Processor), 每個邏輯處理器都有獨立的處理器狀態,但共享Core內部的計算資源,如ALU,FPU,L1,L2緩存。 這樣在最小的硬件投入下提高了CPU在多線程軟件工作負載下的性能,提高了硬件使用效率。 x86的超線程技術出現早於NUMA架構。

本地內存

在Intel x86平臺上,所謂本地內存,就是CPU可以經過Uncore部件裏的iMC訪問到的內存。而那些非本地的, 遠程內存(Remote Memory),則需要經過QPI的鏈路到該內存所在的本地CPU的iMC來訪問。 曾經在Intel IvyBridge的NUMA平臺上做的內存訪問性能測試顯示,遠程內存訪問的延時時本地內存的一倍。

可以假設,操作系統應該儘量利用本地內存的低訪問延遲特性來優化應用和系統的性能。

本地 IO 資源

如前所述,Intel自從SandyBridge處理器開始,已經把PCIe Root Complex集成到CPU裏了。 正因爲如此,從CPU直接引出PCIe Root Port的PCIe 3.0的鏈路可以直接與PCIe Switch或者PCIe Endpoint相連。 一個PCIe Endpoint就是一個PCIe外設。這就意味着,對某個PCIe外設來說,如果它直接於哪個CPU相連, 它就屬於哪個CPU所在的NUMA Node。

與本地內存一樣,所謂本地IO資源,就是CPU可以經過Uncore部件裏的PCIe Root Complex直接訪問到的IO資源。 如果是非本地IO資源,則需要經過QPI鏈路到該IO資源所屬的CPU,再通過該CPU PCIe Root Complex訪問。 如果同一個NUMA Node內的CPU和內存和另外一個NUMA Node的IO資源發生互操作,因爲要跨越QPI鏈路, 會存在額外的訪問延遲問題。

其它體系結構裏,爲降低外設訪問延遲,也有將IB(Infiniband)總線集成到CPU裏的。 這樣IB設備也屬於NUMA Node的一部分了。

可以假設,操作系統如果是NUMA Aware的話,應該會盡量針對本地IO資源低延遲的優點進行優化。

​​​​​​​

PCIe Root Complex Location

 

NUMA Node 互聯

在Intel x86上,NUMA Node之間的互聯是通過 QPI((QuickPath Interconnect) Link的。 CPU的Uncore部分有QPI的控制器來控制CPU到QPI的數據訪問。

下圖就是一個利用 QPI Switch 互聯的 8 NUMA Node 的 x86 系統,

img

img

 

NUMA Affinity

NUMA Affinity(親和性)是和NUMA Hierarchy(層級結構)直接相關的。對系統軟件來說, 以下兩個概念至關重要,

  • CPU NUMA Affinity

    CPU NUMA的親和性是指從CPU角度看,哪些內存訪問更快,有更低的延遲。如前所述, 和該CPU直接相連的本地內存是更快的。操作系統如果可以根據任務所在CPU去分配本地內存, 就是基於CPU NUMA親和性的考慮。因此,CPU NUMA親和性就是要儘量讓任務運行在本地的NUMA Node裏。

  • Device NUMA Affinity

    設備NUMA親和性是指從PCIe外設的角度看,如果和CPU和內存相關的IO活動都發生在外設所屬的NUMA Node, 將會有更低延遲。這裏有兩種設備NUMA親和性的問題,

    1. DMA Buffer NUMA Affinity

      大部分PCIe設備支持DMA功能的。也就是說,設備可以直接把數據寫入到位於內存中的DMA緩衝區。 顯然,如果DMA緩衝區在PCIe外設所屬的NUMA Node裏分配,那麼將會有最低的延遲。 否則,外設的DMA操作要跨越QPI鏈接去讀寫另外一個NUMA Node裏的DMA緩衝區。 因此,操作系統如果可以根據PCIe設備所屬的NUMA node分配DMA緩衝區, 將會有最好的DMA操作的性能。

    2. Interrupt NUMA Affinity

      設備DMA操作完成後,需要在CPU上觸發中斷來通知驅動程序的中斷處理例程(ISR)來讀寫DMA緩衝區。 很多時候,ISR觸發下半部機制(SoftIRQ)來進入到協議棧相關(Network,Storage)的代碼路徑來傳送數據。 對大部分操作系統來說,硬件中斷(HardIRQ)和下半部機制的代碼在同一個CPU上發生。 因此,DMA緩衝區的讀寫操作發生的位置和設備硬件中斷(HardIRQ)密切相關。假設操作系統可以把設備的硬件中斷綁定到自己所屬的NUMA node, 那之後中斷處理函數和協議棧代碼對DMA緩衝區的讀寫將會有更低的延遲。

Firmware 接口

由於NUMA的親和性對應用的性能非常重要,那麼硬件平臺就需要給操作系統提供接口機制來感知硬件的NUMA層級結構。 在x86平臺,ACPI規範提供了以下接口來讓操作系統來檢測系統的NUMA層級結構。

ACPI 5.0a規範的第17章是有關NUMA的章節。ACPI規範裏,NUMA Node被第9章定義的Module Device所描述。 ACPI規範裏用Proximity Domain對NUMA Node做了抽象,兩者的概念大多時候等同。

  • SRAT(System Resource Affinity Table)

    主要描述了系統boot時的CPU和內存都屬於哪個Proximity Domain(NUMA Node)。 這個表格裏的信息時靜態的,如果是啓動後熱插拔,需要用OSPM的_PXM方法去獲得相關信息。

  • SLIT(System Locality Information Table)

    提供CPU和內存之間的位置遠近信息。在SRAT表格裏,只能告訴給定的CPU和內存是否在一個NUMA Node。 對某個CPU來說,不在本NUMA Node裏的內存,即遠程內存們是否都是一樣的訪問延遲取決於NUMA的拓撲有多複雜(QPI的跳數)。 總之,對於不能簡單用遠近來描述的NUMA系統(QPI存在0,1,2等不同跳數), 需要SLIT表格給出進一步的說明。同樣的,這個表格也是靜態表格,熱插拔需要使用OSPM的_SLI方法。

  • DSDT(Differentiated System Description Table)

    從Device NUMA角度看,這個表格給出了系統boot時的外設都屬於哪個Proximity Domain(NUMA Node)。

ACPI規範OSPM(Operating System-directed configuration and Power Management) 和OSPM各種方法就是操作系統裏的ACPI驅動和ACPI firmware之間的一個互動的接口。 x86啓動OS後,沒有ACPI之前,firmware(BIOS)的代碼是無法被執行了,除非通過SMI中斷處理程序。 但有了ACPI,BIOS提前把ACPI的一些靜態表格和AML的bytecode代碼裝載到內存, 然後ACPI驅動就會加載AML的解釋器,這樣OS就可以通過ACPI驅動調用預先裝載的AML代碼。 AML(ACPI Machine Language)是和Java類似的一種虛擬機解釋型語言,所以不同操作系統的ACPI驅動, 只要有相同的虛擬機解釋器,就可以直接從操作系統調用ACPI寫好的AML的代碼了。 所以,前文所述的所有熱插拔的OSPM方法,其實就是對應ACPI firmware的AML的一段函數代碼而已。 (關於ACPI的簡單介紹,這裏給出兩篇延伸閱讀:1 2。)

NUMA Optimization

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章