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 编号都保持不变。 这仅仅是一个实现细节,没有实际影响。

  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