4. x86 拓扑结构

本文档记录并阐明了内核中 x86 拓扑建模和表示的主要方面。当对相关代码进行更改时,请更新/修改。

架构无关的拓扑定义在 如何通过 sysfs 导出 CPU 拓扑信息 中。此文件保存了 x86 特定的差异/特殊性,这些差异/特殊性不一定适用于通用定义。因此,在 x86 上读取 Linux 拓扑的方法是从通用定义开始,并同时查看此文件以了解 x86 的具体细节。

不用说,代码应该使用通用函数 - 此文件用于记录 x86 拓扑的内部工作原理。

由 Thomas Gleixner <tglx@linutronix.de> 和 Borislav Petkov <bp@alien8.de> 发起。

拓扑设施的主要目的是为需要知道/查询/使用正在运行的系统关于线程、核心、封装等结构的的代码提供适当的接口。

内核并不关心物理插槽的概念,因为插槽与软件无关。它是一个机电组件。过去,一个插槽总是包含一个封装(见下文),但是随着多芯片模块 (MCM) 的出现,一个插槽可以容纳多个封装。因此,代码中可能仍然有对插槽的引用,但它们具有历史性质,应该被清理掉。

系统的拓扑结构以以下单元描述:

  • 封装

  • 核心

  • 线程

4.1. 封装

封装包含多个核心以及共享资源,例如 DRAM 控制器、共享缓存等。

现代系统也可能使用术语“Die”来表示封装。

AMD 的封装术语是“节点”。

内核中与封装相关的拓扑信息

  • 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 上,包含末级缓存的节点 ID 或核心复合体 ID。通常,它是一个在系统上唯一标识 LLC 的数字。

4.2. 核心

一个核心由 1 个或多个线程组成。线程是 SMT 型线程还是 CMT 型线程无关紧要。

AMD 对 CMT 核心的术语是“计算单元”。内核始终使用“核心”。

4.3. 线程

线程是单个调度单元。它等同于逻辑 Linux CPU。

AMD 对 CMT 线程的术语是“计算单元核心”。内核始终使用“线程”。

内核中与线程相关的拓扑信息

  • 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” 中。

4.4. 系统拓扑示例

注意

备选的 Linux CPU 枚举取决于 BIOS 如何枚举线程。许多 BIOS 首先枚举所有线程 0,然后枚举所有线程 1。这样做的好处是,无论是否启用线程,线程 0 的逻辑 Linux CPU 编号都保持不变。这仅仅是一个实现细节,没有实际影响。

  1. 单封装,单核

    [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
    
  2. 单封装,双核

    1. 每个核心一个线程

      [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
                  -> [core 1] -> [thread 0] -> Linux CPU 1
      
    2. 每个核心两个线程

      [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 3
      

      AMD 对 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
      
  1. 双封装,双核

    1. 每个核心一个线程

      [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
      
    2. 每个核心两个线程

      [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 7
      

      AMD 对 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