4. x86 拓撲結構¶
本文件記錄並闡明瞭核心中 x86 拓撲建模和表示的主要方面。在對相關程式碼進行更改時,請更新/修改。
架構無關的拓撲定義位於 CPU 拓撲資訊如何透過 sysfs 匯出。 此檔案包含 x86 特定的差異/特殊性,這些差異/特殊性不一定適用於通用定義。 因此,閱讀 Linux 上 x86 拓撲結構的方式是從通用拓撲結構開始,並並行檢視此檔案,瞭解 x86 的具體細節。
毋庸置疑,程式碼應該使用通用函式 - 此檔案僅用於記錄 x86 拓撲結構的內部工作原理。
由 Thomas Gleixner <tglx@linutronix.de> 和 Borislav Petkov <bp@alien8.de> 發起。
拓撲結構設施的主要目標是為需要了解/查詢/使用執行系統結構的執行緒、核心、包等程式碼提供足夠的介面。
核心不關心物理插槽的概念,因為插槽與軟體無關。它是一個機電裝置元件。過去,一個插槽總是包含一個包(見下文),但隨著多晶片模組 (MCM) 的出現,一個插槽可以容納多個包。因此,程式碼中可能仍然存在對插槽的引用,但它們具有歷史性質,應該進行清理。
系統的拓撲結構以以下單位描述:
包
核心
執行緒
4.1. 包¶
包包含多個核心以及共享資源,例如 DRAM 控制器、共享快取等。
現代系統也可以使用術語 “Die” 來表示包。
AMD 用於包的命名法是 “Node”。
核心中與包相關的拓撲資訊
topology_num_threads_per_package()
一個包中的執行緒數。
topology_num_cores_per_package()
一個包中的核心數。
topology_max_dies_per_package()
一個包中的最大 die 數。
cpuinfo_x86.topo.die_id
die 的物理 ID。
cpuinfo_x86.topo.pkg_id
包的物理 ID。 此資訊透過 CPUID 檢索,並從包中核心的 APIC ID 推斷出來。
現代系統使用此值作為插槽。 一個插槽中可能存在多個包。 此值可能與 topo.die_id 不同。
cpuinfo_x86.topo.logical_pkg_id
包的邏輯 ID。 由於我們不信任 BIOS 以一致的方式列舉包,因此我們引入了邏輯包 ID 的概念,以便我們可以合理地計算系統中可能的最大包數,並使包線性列舉。
topology_max_packages()
系統中可能的最大包數。 有助於每個包的設施預先分配每個包的資訊。
cpuinfo_x86.topo.llc_id
在英特爾上,共享末級快取的 CPU 列表的第一個 APIC ID
在 AMD 上,包含末級快取的 Node ID 或 Core Complex ID。 通常,它是一個唯一標識系統上 LLC 的數字。
4.2. 核心¶
一個核心由 1 個或多個執行緒組成。執行緒是 SMT 型別還是 CMT 型別並不重要。
AMD 用於 CMT 核心的命名法是 “Compute Unit”。核心始終使用 “core”。
4.3. 執行緒¶
執行緒是單個排程單元。它相當於一個邏輯 Linux CPU。
AMD 用於 CMT 執行緒的命名法是 “Compute Unit Core”。核心始終使用 “thread”。
核心中與執行緒相關的拓撲資訊
topology_core_cpumask()
cpumask 包含包中執行緒所屬的所有線上執行緒。
線上執行緒的數量也列印在 /proc/cpuinfo “siblings” 中。
topology_sibling_cpumask()
cpumask 包含核心中執行緒所屬的所有線上執行緒。
topology_logical_package_id()
執行緒所屬的邏輯包 ID。
topology_physical_package_id()
執行緒所屬的物理包 ID。
topology_core_id();
執行緒所屬核心的 ID。 它也列印在 /proc/cpuinfo “core_id” 中。
topology_logical_core_id();
執行緒所屬的邏輯核心 ID。
4.4. 系統拓撲示例¶
注意
替代 Linux CPU 列舉取決於 BIOS 如何列舉執行緒。 許多 BIOS 首先列舉所有執行緒 0,然後列舉所有執行緒 1。 這樣做的好處是,無論是否啟用執行緒,執行緒 0 的邏輯 Linux CPU 編號都保持不變。 這僅僅是一個實現細節,沒有實際影響。
單包、單核
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
單包、雙核
每個核心一個執行緒
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1每個核心兩個執行緒
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3替代列舉
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 3AMD 用於 CMT 系統的命名法
[node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3
雙包、雙核
每個核心一個執行緒
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 3每個核心兩個執行緒
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4 -> [thread 1] -> Linux CPU 5 -> [core 1] -> [thread 0] -> Linux CPU 6 -> [thread 1] -> Linux CPU 7替代列舉
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 4 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 5 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 6 -> [core 1] -> [thread 0] -> Linux CPU 3 -> [thread 1] -> Linux CPU 7AMD 用於 CMT 系統的命名法
[node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3 [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4 -> [Compute Unit Core 1] -> Linux CPU 5 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6 -> [Compute Unit Core 1] -> Linux CPU 7