sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget%/translations/zh_CN/arch/x86/topologymodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/zh_TW/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/it_IT/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ja_JP/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ko_KR/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/pt_BR/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/sp_SP/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh?/var/lib/git/docbuild/linux/Documentation/arch/x86/topology.rsthKubhsection)}(hhh](htitle)}(h x86 Topologyh]h x86 Topology}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hThis documents and clarifies the main aspects of x86 topology modelling and representation in the kernel. Update/change when doing changes to the respective code.h]hThis documents and clarifies the main aspects of x86 topology modelling and representation in the kernel. Update/change when doing changes to the respective code.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hX^The architecture-agnostic topology definitions are in Documentation/admin-guide/cputopology.rst. This file holds x86-specific differences/specialities which must not necessarily apply to the generic definitions. Thus, the way to read up on Linux topology on x86 is to start with the generic one and look at this one in parallel for the x86 specifics.h]hX^The architecture-agnostic topology definitions are in Documentation/admin-guide/cputopology.rst. This file holds x86-specific differences/specialities which must not necessarily apply to the generic definitions. Thus, the way to read up on Linux topology on x86 is to start with the generic one and look at this one in parallel for the x86 specifics.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hNeedless to say, code should use the generic functions - this file is *only* here to *document* the inner workings of x86 topology.h](hFNeedless to say, code should use the generic functions - this file is }(hhhhhNhNubhemphasis)}(h*only*h]honly}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhubh here to }(hhhhhNhNubj)}(h *document*h]hdocument}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhubh$ the inner workings of x86 topology.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hPStarted by Thomas Gleixner and Borislav Petkov .h](hStarted by Thomas Gleixner <}(hj/hhhNhNubh reference)}(htglx@kernel.orgh]htglx@kernel.org}(hj9hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:tglx@kernel.orguh1j7hj/ubh> and Borislav Petkov <}(hj/hhhNhNubj8)}(h bp@alien8.deh]h bp@alien8.de}(hjMhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:bp@alien8.deuh1j7hj/ubh>.}(hj/hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hThe main aim of the topology facilities is to present adequate interfaces to code which needs to know/query/use the structure of the running system wrt threads, cores, packages, etc.h]hThe main aim of the topology facilities is to present adequate interfaces to code which needs to know/query/use the structure of the running system wrt threads, cores, packages, etc.}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXThe kernel does not care about the concept of physical sockets because a socket has no relevance to software. It's an electromechanical component. In the past a socket always contained a single package (see below), but with the advent of Multi Chip Modules (MCM) a socket can hold more than one package. So there might be still references to sockets in the code, but they are of historical nature and should be cleaned up.h]hXThe kernel does not care about the concept of physical sockets because a socket has no relevance to software. It’s an electromechanical component. In the past a socket always contained a single package (see below), but with the advent of Multi Chip Modules (MCM) a socket can hold more than one package. So there might be still references to sockets in the code, but they are of historical nature and should be cleaned up.}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(h6The topology of a system is described in the units of:h]h6The topology of a system is described in the units of:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hhhhubh block_quote)}(h- packages - cores - threads h]h bullet_list)}(hhh](h list_item)}(hpackagesh]h)}(hjh]hpackages}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hcoresh]h)}(hjh]hcores}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hthreads h]h)}(hthreadsh]hthreads}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK%hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhK#hjubah}(h]h ]h"]h$]h&]uh1jhhhK#hhhhubh)}(hhh](h)}(hPackageh]hPackage}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK(ubh)}(hbPackages contain a number of cores plus shared resources, e.g. DRAM controller, shared caches etc.h]hbPackages contain a number of cores plus shared resources, e.g. DRAM controller, shared caches etc.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK)hjhhubh)}(h7Modern systems may also use the term 'Die' for package.h]h;Modern systems may also use the term ‘Die’ for package.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hjhhubh)}(h'AMD nomenclature for package is 'Node'.h]h+AMD nomenclature for package is ‘Node’.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjhhubh)}(h3Package-related topology information in the kernel:h]h3Package-related topology information in the kernel:}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjhhubj)}(hXI- topology_num_threads_per_package() The number of threads in a package. - topology_num_cores_per_package() The number of cores in a package. - topology_max_dies_per_package() The maximum number of dies in a package. - cpuinfo_x86.topo.die_id: The physical ID of the die. - cpuinfo_x86.topo.pkg_id: The physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package. Modern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id. - cpuinfo_x86.topo.logical_pkg_id: The logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly. - topology_max_packages(): The maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information. - cpuinfo_x86.topo.llc_id: - On Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache - On AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h]j)}(hhh](j)}(hHtopology_num_threads_per_package() The number of threads in a package. h](h)}(h"topology_num_threads_per_package()h]h"topology_num_threads_per_package()}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK2hjBubh)}(h#The number of threads in a package.h]h#The number of threads in a package.}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK4hjBubeh}(h]h ]h"]h$]h&]uh1jhj?ubj)}(hDtopology_num_cores_per_package() The number of cores in a package. h](h)}(h topology_num_cores_per_package()h]h topology_num_cores_per_package()}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hjhubh)}(h!The number of cores in a package.h]h!The number of cores in a package.}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjhubeh}(h]h ]h"]h$]h&]uh1jhj?ubj)}(hJtopology_max_dies_per_package() The maximum number of dies in a package. h](h)}(htopology_max_dies_per_package()h]htopology_max_dies_per_package()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hjubh)}(h(The maximum number of dies in a package.h]h(The maximum number of dies in a package.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe physical ID of the die.h]hThe physical ID of the die.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK@hjubeh}(h]h ]h"]h$]h&]uh1jhj?ubj)}(hX$cpuinfo_x86.topo.pkg_id: The physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package. Modern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id. h](h)}(hcpuinfo_x86.topo.pkg_id:h]hcpuinfo_x86.topo.pkg_id:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhjubh)}(hThe physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package.h]hThe physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjubh)}(hModern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id.h]hModern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhjubeh}(h]h ]h"]h$]h&]uh1jhj?ubj)}(hX6cpuinfo_x86.topo.logical_pkg_id: The logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly. h](h)}(h cpuinfo_x86.topo.logical_pkg_id:h]h cpuinfo_x86.topo.logical_pkg_id:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjubh)}(hXThe logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly.h]hXThe logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKLhjubeh}(h]h ]h"]h$]h&]uh1jhj?ubj)}(htopology_max_packages(): The maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information. h](h)}(htopology_max_packages():h]htopology_max_packages():}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKQhj4ubh)}(hThe maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information.h]hThe maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information.}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKShj4ubeh}(h]h ]h"]h$]h&]uh1jhj?ubj)}(hX cpuinfo_x86.topo.llc_id: - On Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache - On AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h](h)}(hcpuinfo_x86.topo.llc_id:h]hcpuinfo_x86.topo.llc_id:}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKVhjZubj)}(h- On Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache - On AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h]j)}(hhh](j)}(hMOn Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache h]h)}(hLOn Intel, the first APIC ID of the list of CPUs sharing the Last Level Cacheh]hLOn Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKXhjsubah}(h]h ]h"]h$]h&]uh1jhjpubj)}(hOn AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h]h)}(hOn AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system.h]hOn AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK[hjubah}(h]h ]h"]h$]h&]uh1jhjpubeh}(h]h ]h"]h$]h&]jjuh1jhhhKXhjlubah}(h]h ]h"]h$]h&]uh1jhhhKXhjZubeh}(h]h ]h"]h$]h&]uh1jhj?ubeh}(h]h ]h"]h$]h&]jjuh1jhhhK2hj;ubah}(h]h ]h"]h$]h&]uh1jhhhK2hjhhubeh}(h]packageah ]h"]packageah$]h&]uh1hhhhhhhhK(ubh)}(hhh](h)}(hCoresh]hCores}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK`ubh)}(hjA core consists of 1 or more threads. It does not matter whether the threads are SMT- or CMT-type threads.h]hjA core consists of 1 or more threads. It does not matter whether the threads are SMT- or CMT-type threads.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKahjhhubh)}(hRAMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses "core".h]hZAMDs nomenclature for a CMT core is “Compute Unit”. The kernel always uses “core”.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKdhjhhubeh}(h]coresah ]h"]coresah$]h&]uh1hhhhhhhhK`ubh)}(hhh](h)}(hThreadsh]hThreads}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKhubh)}(hQA thread is a single scheduling unit. It's the equivalent to a logical Linux CPU.h]hSA thread is a single scheduling unit. It’s the equivalent to a logical Linux CPU.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKihjhhubh)}(hZAMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always uses "thread".h]hbAMDs nomenclature for CMT threads is “Compute Unit Core”. The kernel always uses “thread”.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKlhjhhubh)}(h2Thread-related topology information in the kernel:h]h2Thread-related topology information in the kernel:}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKohjhhubj)}(hX- topology_core_cpumask(): The cpumask contains all online threads in the package to which a thread belongs. The number of online threads is also printed in /proc/cpuinfo "siblings." - topology_sibling_cpumask(): The cpumask contains all online threads in the core to which a thread belongs. - topology_logical_package_id(): The logical package ID to which a thread belongs. - topology_physical_package_id(): The physical package ID to which a thread belongs. - topology_core_id(); The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo "core_id." - topology_logical_core_id(); The logical core ID to which a thread belongs. h]j)}(hhh](j)}(htopology_core_cpumask(): The cpumask contains all online threads in the package to which a thread belongs. The number of online threads is also printed in /proc/cpuinfo "siblings." h](h)}(htopology_core_cpumask():h]htopology_core_cpumask():}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKqhj@ubh)}(hQThe cpumask contains all online threads in the package to which a thread belongs.h]hQThe cpumask contains all online threads in the package to which a thread belongs.}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKshj@ubh)}(hIThe number of online threads is also printed in /proc/cpuinfo "siblings."h]hMThe number of online threads is also printed in /proc/cpuinfo “siblings.”}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKvhj@ubeh}(h]h ]h"]h$]h&]uh1jhj=ubj)}(hltopology_sibling_cpumask(): The cpumask contains all online threads in the core to which a thread belongs. h](h)}(htopology_sibling_cpumask():h]htopology_sibling_cpumask():}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhjtubh)}(hNThe cpumask contains all online threads in the core to which a thread belongs.h]hNThe cpumask contains all online threads in the core to which a thread belongs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhjtubeh}(h]h ]h"]h$]h&]uh1jhj=ubj)}(hRtopology_logical_package_id(): The logical package ID to which a thread belongs. h](h)}(htopology_logical_package_id():h]htopology_logical_package_id():}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK}hjubh)}(h1The logical package ID to which a thread belongs.h]h1The logical package ID to which a thread belongs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhj=ubj)}(hTtopology_physical_package_id(): The physical package ID to which a thread belongs. h](h)}(htopology_physical_package_id():h]htopology_physical_package_id():}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h2The physical package ID to which a thread belongs.h]h2The physical package ID to which a thread belongs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhj=ubj)}(hrtopology_core_id(); The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo "core_id." h](h)}(htopology_core_id();h]htopology_core_id();}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h\The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo "core_id."h]h`The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo “core_id.”}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhj=ubj)}(hNtopology_logical_core_id(); The logical core ID to which a thread belongs. h](h)}(htopology_logical_core_id();h]htopology_logical_core_id();}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubh)}(h.The logical core ID to which a thread belongs.h]h.The logical core ID to which a thread belongs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubeh}(h]h ]h"]h$]h&]uh1jhj=ubeh}(h]h ]h"]h$]h&]jjuh1jhhhKqhj9ubah}(h]h ]h"]h$]h&]uh1jhhhKqhjhhubeh}(h]threadsah ]h"]threadsah$]h&]uh1hhhhhhhhKhubh)}(hhh](h)}(hSystem topology enumerationh]hSystem topology enumeration}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFhhhhhKubh)}(hThe topology on x86 systems can be discovered using a combination of vendor specific CPUID leaves which enumerate the processor topology and the cache hierarchy.h]hThe topology on x86 systems can be discovered using a combination of vendor specific CPUID leaves which enumerate the processor topology and the cache hierarchy.}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjFhhubh)}(hWThe CPUID leaves in their preferred order of parsing for each x86 vendor is as follows:h]hWThe CPUID leaves in their preferred order of parsing for each x86 vendor is as follows:}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjFhhubhenumerated_list)}(hhh](j)}(hXAMD 1) CPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology) The extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level. Support for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel` in `EBX[15:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket. The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from `ExtendedLocalApicId` in `EDX[31:0]` in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. CPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics. If CPUID leaf 0x80000026 is supported, further parsing is not required. 2) CPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum) The extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology. The support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain that the level describes - Thread, or Processor (Socket). The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from the `ExtendedLocalApicId` in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level. If CPUID leaf 0xB is supported, further parsing is not required. 3) CPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId) If neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX. The support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008. The shifts from the APIC ID for the Socket ID is calculated from the `ApicIdSize` field in `ECX[15:12]` if it is non-zero. If `ApicIdSize` is reported to be zero, the shift is calculated as the order of the `number of threads` calculated from `NC` field in `ECX[7:0]` which describes the `number of threads - 1` on the package. Unless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]`. The topology parsing continues to detect if Extended APIC ID is supported or not. 4) CPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId}) The support for Extended APIC ID can be detected by checking for the presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx). If Topology Extensions is supported, the APIC ID from `ExtendedApicId` from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology enumeration. On processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of `number of threads per core` calculated using the `ThreadsPerCore` field in `EBX[15:8]` which describes `number of threads per core - 1`. On Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the `cu_id` (Compute Unit ID) to detect CPUs that share the compute units. All AMD processors that support the `TopologyExtensions` feature store the `NodeId` from the `ECX[7:0]` of CPUID leaf 0x8000001E (Core::X86::Cpuid::NodeId) as the per-CPU `node_id`. On older processors, the `node_id` was discovered using MSR_FAM10H_NODE_ID MSR (MSR 0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking `ECX[19]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx). h](h)}(hAMDh]hAMD}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjxubjt)}(hhh](j)}(hXhCPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology) The extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level. Support for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel` in `EBX[15:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket. The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from `ExtendedLocalApicId` in `EDX[31:0]` in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. CPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics. If CPUID leaf 0x80000026 is supported, further parsing is not required. h](h)}(hOCPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology)h]hOCPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level.h]hThe extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hSupport for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel` in `EBX[15:0]` at a particular level (starting from 0) is non-zero.h](hySupport for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if }(hjhhhNhNubhtitle_reference)}(h`LogProcAtThisLevel`h]hLogProcAtThisLevel}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `EBX[15:0]`h]h EBX[15:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh5 at a particular level (starting from 0) is non-zero.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe `LevelType` in `ECX[15:8]` at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket.h](hThe }(hjhhhNhNubj)}(h `LevelType`h]h LevelType}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `ECX[15:8]`h]h ECX[15:8]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhh at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hXThe kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from `ExtendedLocalApicId` in `EDX[31:0]` in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.h](hThe kernel uses the }(hjhhhNhNubj)}(h`CoreMaskWidth`h]h CoreMaskWidth}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh from }(hjhhhNhNubj)}(h `EAX[4:0]`h]hEAX[4:0]}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhC to discover the number of bits that need to be right-shifted from }(hjhhhNhNubj)}(h`ExtendedLocalApicId`h]hExtendedLocalApicId}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `EDX[31:0]`h]h EDX[31:0]}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hCPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics.h]hCPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics.}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hGIf CPUID leaf 0x80000026 is supported, further parsing is not required.h]hGIf CPUID leaf 0x80000026 is supported, further parsing is not required.}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hXCPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum) The extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology. The support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain that the level describes - Thread, or Processor (Socket). The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from the `ExtendedLocalApicId` in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level. If CPUID leaf 0xB is supported, further parsing is not required. h](h)}(hTCPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum)h]hTCPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology.h]hThe extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level (starting from 0) is non-zero.h](hnThe support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if }(hjhhhNhNubj)}(h `EBX[31:0]`h]h EBX[31:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh5 at a particular level (starting from 0) is non-zero.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe `LevelType` in `ECX[15:8]` at the level provides the topology domain that the level describes - Thread, or Processor (Socket).h](hThe }(hjhhhNhNubj)}(h `LevelType`h]h LevelType}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `ECX[15:8]`h]h ECX[15:8]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhd at the level provides the topology domain that the level describes - Thread, or Processor (Socket).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hXThe kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from the `ExtendedLocalApicId` in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level.h](hThe kernel uses the }(hjhhhNhNubj)}(h`CoreMaskWidth`h]h CoreMaskWidth}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh from }(hjhhhNhNubj)}(h `EAX[4:0]`h]hEAX[4:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhG to discover the number of bits that need to be right-shifted from the }(hjhhhNhNubj)}(h`ExtendedLocalApicId`h]hExtendedLocalApicId}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `EDX[31:0]`h]h EDX[31:0]}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhu to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h@If CPUID leaf 0xB is supported, further parsing is not required.h]h@If CPUID leaf 0xB is supported, further parsing is not required.}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hXCPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId) If neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX. The support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008. The shifts from the APIC ID for the Socket ID is calculated from the `ApicIdSize` field in `ECX[15:12]` if it is non-zero. If `ApicIdSize` is reported to be zero, the shift is calculated as the order of the `number of threads` calculated from `NC` field in `ECX[7:0]` which describes the `number of threads - 1` on the package. Unless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]`. The topology parsing continues to detect if Extended APIC ID is supported or not. h](h)}(hGCPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId)h]hGCPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId)}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjgubh)}(hIf neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX.h]hIf neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX.}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjgubh)}(hjThe support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008.h]hjThe support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjgubh)}(hzThe shifts from the APIC ID for the Socket ID is calculated from the `ApicIdSize` field in `ECX[15:12]` if it is non-zero.h](hEThe shifts from the APIC ID for the Socket ID is calculated from the }(hjhhhNhNubj)}(h `ApicIdSize`h]h ApicIdSize}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field in }(hjhhhNhNubj)}(h `ECX[15:12]`h]h ECX[15:12]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh if it is non-zero.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjgubh)}(hIf `ApicIdSize` is reported to be zero, the shift is calculated as the order of the `number of threads` calculated from `NC` field in `ECX[7:0]` which describes the `number of threads - 1` on the package.h](hIf }(hjhhhNhNubj)}(h `ApicIdSize`h]h ApicIdSize}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhE is reported to be zero, the shift is calculated as the order of the }(hjhhhNhNubj)}(h`number of threads`h]hnumber of threads}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh calculated from }(hjhhhNhNubj)}(h`NC`h]hNC}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field in }(hjhhhNhNubj)}(h `ECX[7:0]`h]hECX[7:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh which describes the }(hjhhhNhNubj)}(h`number of threads - 1`h]hnumber of threads - 1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh on the package.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjgubh)}(hUnless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]`.h](hYUnless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the }(hj/hhhNhNubj)}(h `LocalApicId`h]h LocalApicId}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj/ubh field of CPUID leaf 0x00000001 }(hj/hhhNhNubj)}(h `EBX[31:24]`h]h EBX[31:24]}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj/ubh.}(hj/hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjgubh)}(hQThe topology parsing continues to detect if Extended APIC ID is supported or not.h]hQThe topology parsing continues to detect if Extended APIC ID is supported or not.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjgubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hXCPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId}) The support for Extended APIC ID can be detected by checking for the presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx). If Topology Extensions is supported, the APIC ID from `ExtendedApicId` from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology enumeration. On processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of `number of threads per core` calculated using the `ThreadsPerCore` field in `EBX[15:8]` which describes `number of threads per core - 1`. On Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the `cu_id` (Compute Unit ID) to detect CPUs that share the compute units. h](h)}(hzCPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId})h]hzCPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId})}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjuubh)}(hThe support for Extended APIC ID can be detected by checking for the presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).h](hQThe support for Extended APIC ID can be detected by checking for the presence of }(hjhhhNhNubj)}(h`TopologyExtensions`h]hTopologyExtensions}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `ECX[22]`h]hECX[22]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhT of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjuubh)}(hIf Topology Extensions is supported, the APIC ID from `ExtendedApicId` from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology enumeration.h](h6If Topology Extensions is supported, the APIC ID from }(hjhhhNhNubj)}(h`ExtendedApicId`h]hExtendedApicId}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh from CPUID leaf 0x8000001E }(hjhhhNhNubj)}(h `EAX[31:0]`h]h EAX[31:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh$ should be preferred over that from }(hjhhhNhNubj)}(h `LocalApicId`h]h LocalApicId}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field of CPUID leaf 0x00000001 }(hjhhhNhNubj)}(h `EBX[31:24]`h]h EBX[31:24]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh for topology enumeration.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjuubh)}(hX:On processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of `number of threads per core` calculated using the `ThreadsPerCore` field in `EBX[15:8]` which describes `number of threads per core - 1`.h](hOn processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of }(hj hhhNhNubj)}(h`number of threads per core`h]hnumber of threads per core}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh calculated using the }(hj hhhNhNubj)}(h`ThreadsPerCore`h]hThreadsPerCore}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh field in }(hj hhhNhNubj)}(h `EBX[15:8]`h]h EBX[15:8]}(hj; hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh which describes }(hj hhhNhNubj)}(h `number of threads per core - 1`h]hnumber of threads per core - 1}(hjM hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjuubh)}(hOn Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the `cu_id` (Compute Unit ID) to detect CPUs that share the compute units.h](h/On Processors of Family 0x15, the Core ID from }(hje hhhNhNubj)}(h `EBX[7:0]`h]hEBX[7:0]}(hjm hhhNhNubah}(h]h ]h"]h$]h&]uh1jhje ubh is used as the }(hje hhhNhNubj)}(h`cu_id`h]hcu_id}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhje ubh? (Compute Unit ID) to detect CPUs that share the compute units.}(hje hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjuubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix)uh1jshjxubh)}(hXAll AMD processors that support the `TopologyExtensions` feature store the `NodeId` from the `ECX[7:0]` of CPUID leaf 0x8000001E (Core::X86::Cpuid::NodeId) as the per-CPU `node_id`. On older processors, the `node_id` was discovered using MSR_FAM10H_NODE_ID MSR (MSR 0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking `ECX[19]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).h](h$All AMD processors that support the }(hj hhhNhNubj)}(h`TopologyExtensions`h]hTopologyExtensions}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh feature store the }(hj hhhNhNubj)}(h`NodeId`h]hNodeId}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh from the }(hj hhhNhNubj)}(h `ECX[7:0]`h]hECX[7:0]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhD of CPUID leaf 0x8000001E (Core::X86::Cpuid::NodeId) as the per-CPU }(hj hhhNhNubj)}(h `node_id`h]hnode_id}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh. On older processors, the }(hj hhhNhNubj)}(h `node_id`h]hnode_id}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh{ was discovered using MSR_FAM10H_NODE_ID MSR (MSR 0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking }(hj hhhNhNubj)}(h `ECX[19]`h]hECX[19]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhT of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjxubeh}(h]h ]h"]h$]h&]uh1jhjuhhhhhNubj)}(hX Intel On Intel platforms, the CPUID leaves that enumerate the processor topology are as follows: 1) CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf) The CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level. The support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket. The kernel uses the value from `EAX[4:0]` to discover the number of bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]` to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. If CPUID leaf 0x1F is supported, further parsing is not required. 2) CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf) The extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology. The support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if `EBX[31:0]` at a particular level (starting from 0) is non-zero. CPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner. If CPUID leaf 0xB is supported, further parsing is not required. 3) CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) On Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache. Processors that feature Hyper-Threading is detected using `EDX[28]` of CPUID leaf 0x1 (Basic CPUID Information). The order of `Maximum number of addressable IDs for logical processors sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID. The APIC ID and Package information is computed using the data from CPUID leaf 0x1. 4) CPUID leaf 0x00000001 (Basic CPUID Information) The mask and shifts to derive the Physical Package (socket) ID is computed using the `Maximum number of addressable IDs for logical processors in this physical package` from `EBX[23:16]` of CPUID leaf 0x1. The APIC ID on the legacy platforms is derived from the `Initial APIC ID` field from `EBX[31:24]` of CPUID leaf 0x1. h](h)}(hIntelh]hIntel}(hj, hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj( ubh)}(hZOn Intel platforms, the CPUID leaves that enumerate the processor topology are as follows:h]hZOn Intel platforms, the CPUID leaves that enumerate the processor topology are as follows:}(hj: hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj( ubjt)}(hhh](j)}(hX[CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf) The CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level. The support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket. The kernel uses the value from `EAX[4:0]` to discover the number of bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]` to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. If CPUID leaf 0x1F is supported, further parsing is not required. h](h)}(h7CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf)h]h7CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf)}(hjO hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjK ubh)}(hThe CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level.h]hThe CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level.}(hj] hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjK ubh)}(hThe support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level (starting from 0) is non-zero.h](hdThe support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then }(hjk hhhNhNubj)}(h `EBX[31:0]`h]h EBX[31:0]}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjk ubh5 at a particular level (starting from 0) is non-zero.}(hjk hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hjK ubh)}(hThe `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket.h](hThe }(hj hhhNhNubj)}(h `Domain Type`h]h Domain Type}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh in }(hj hhhNhNubj)}(h `ECX[15:8]`h]h ECX[15:8]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhu of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjK ubh)}(hXThe kernel uses the value from `EAX[4:0]` to discover the number of bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]` to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.h](hThe kernel uses the value from }(hj hhhNhNubj)}(h `EAX[4:0]`h]hEAX[4:0]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhG to discover the number of bits that need to be right shifted from the }(hj hhhNhNubj)}(h `x2APIC ID`h]h x2APIC ID}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh in }(hj hhhNhNubj)}(h `EDX[31:0]`h]h EDX[31:0]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhv to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjK ubh)}(hAIf CPUID leaf 0x1F is supported, further parsing is not required.h]hAIf CPUID leaf 0x1F is supported, further parsing is not required.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjK ubeh}(h]h ]h"]h$]h&]uh1jhjH ubj)}(hXUCPUID leaf 0x0000000B (Extended Topology Enumeration Leaf) The extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology. The support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if `EBX[31:0]` at a particular level (starting from 0) is non-zero. CPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner. If CPUID leaf 0xB is supported, further parsing is not required. h](h)}(h:CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf)h]h:CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(hThe extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology.h]hThe extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology.}(hj' hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(hThe support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if `EBX[31:0]` at a particular level (starting from 0) is non-zero.h](hnThe support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if }(hj5 hhhNhNubj)}(h `EBX[31:0]`h]h EBX[31:0]}(hj= hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj5 ubh5 at a particular level (starting from 0) is non-zero.}(hj5 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM!hj ubh)}(hmCPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner.h]hmCPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner.}(hjU hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hj ubh)}(h@If CPUID leaf 0xB is supported, further parsing is not required.h]h@If CPUID leaf 0xB is supported, further parsing is not required.}(hjc hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM(hj ubeh}(h]h ]h"]h$]h&]uh1jhjH ubj)}(hX{CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) On Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache. Processors that feature Hyper-Threading is detected using `EDX[28]` of CPUID leaf 0x1 (Basic CPUID Information). The order of `Maximum number of addressable IDs for logical processors sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID. The APIC ID and Package information is computed using the data from CPUID leaf 0x1. h](h)}(h;CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf)h]h;CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf)}(hj{ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM+hjw ubh)}(hOn Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache.h]hOn Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM-hjw ubh)}(hpProcessors that feature Hyper-Threading is detected using `EDX[28]` of CPUID leaf 0x1 (Basic CPUID Information).h](h:Processors that feature Hyper-Threading is detected using }(hj hhhNhNubj)}(h `EDX[28]`h]hEDX[28]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh- of CPUID leaf 0x1 (Basic CPUID Information).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM1hjw ubh)}(hThe order of `Maximum number of addressable IDs for logical processors sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID.h](h The order of }(hj hhhNhNubj)}(hM`Maximum number of addressable IDs for logical processors sharing this cache`h]hKMaximum number of addressable IDs for logical processors sharing this cache}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh from }(hj hhhNhNubj)}(h `EAX[25:14]`h]h EAX[25:14]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh^ of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM4hjw ubh)}(hSThe APIC ID and Package information is computed using the data from CPUID leaf 0x1.h]hSThe APIC ID and Package information is computed using the data from CPUID leaf 0x1.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM8hjw ubeh}(h]h ]h"]h$]h&]uh1jhjH ubj)}(hCPUID leaf 0x00000001 (Basic CPUID Information) The mask and shifts to derive the Physical Package (socket) ID is computed using the `Maximum number of addressable IDs for logical processors in this physical package` from `EBX[23:16]` of CPUID leaf 0x1. h](h)}(h/CPUID leaf 0x00000001 (Basic CPUID Information)h]h/CPUID leaf 0x00000001 (Basic CPUID Information)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM<hj ubh)}(hThe mask and shifts to derive the Physical Package (socket) ID is computed using the `Maximum number of addressable IDs for logical processors in this physical package` from `EBX[23:16]` of CPUID leaf 0x1.h](hUThe mask and shifts to derive the Physical Package (socket) ID is computed using the }(hj hhhNhNubj)}(hS`Maximum number of addressable IDs for logical processors in this physical package`h]hQMaximum number of addressable IDs for logical processors in this physical package}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh from }(hj hhhNhNubj)}(h `EBX[23:16]`h]h EBX[23:16]}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh of CPUID leaf 0x1.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM>hj ubeh}(h]h ]h"]h$]h&]uh1jhjH ubeh}(h]h ]h"]h$]h&]j j j hj j uh1jshj( ubj)}(hvThe APIC ID on the legacy platforms is derived from the `Initial APIC ID` field from `EBX[31:24]` of CPUID leaf 0x1. h]h)}(htThe APIC ID on the legacy platforms is derived from the `Initial APIC ID` field from `EBX[31:24]` of CPUID leaf 0x1.h](h8The APIC ID on the legacy platforms is derived from the }(hjQ hhhNhNubj)}(h`Initial APIC ID`h]hInitial APIC ID}(hjY hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQ ubh field from }(hjQ hhhNhNubj)}(h `EBX[31:24]`h]h EBX[31:24]}(hjk hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQ ubh of CPUID leaf 0x1.}(hjQ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMChjM ubah}(h]h ]h"]h$]h&]uh1jhhhMChj( ubeh}(h]h ]h"]h$]h&]uh1jhjuhhhhhNubj)}(hCentaur and Zhaoxin Similar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001 (Basic CPUID Information) to derive the topology information. h](h)}(hCentaur and Zhaoxinh]hCentaur and Zhaoxin}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMGhj ubh)}(hSimilar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001 (Basic CPUID Information) to derive the topology information.h]hSimilar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001 (Basic CPUID Information) to derive the topology information.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMIhj ubeh}(h]h ]h"]h$]h&]uh1jhjuhhhhhNubeh}(h]h ]h"]h$]h&]j j j hj j uh1jshjFhhhhhKubeh}(h]system-topology-enumerationah ]h"]system topology enumerationah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hSystem topology examplesh]hSystem topology examples}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMPubhnote)}(hXVThe alternative Linux CPU enumeration depends on how the BIOS enumerates the threads. Many BIOSes enumerate all threads 0 first and then all threads 1. That has the "advantage" that the logical Linux CPU numbers of threads 0 stay the same whether threads are enabled or not. That's merely an implementation detail and has no practical impact.Dh]h)}(hXVThe alternative Linux CPU enumeration depends on how the BIOS enumerates the threads. Many BIOSes enumerate all threads 0 first and then all threads 1. That has the "advantage" that the logical Linux CPU numbers of threads 0 stay the same whether threads are enabled or not. That's merely an implementation detail and has no practical impact.h]hX\The alternative Linux CPU enumeration depends on how the BIOS enumerates the threads. Many BIOSes enumerate all threads 0 first and then all threads 1. That has the “advantage” that the logical Linux CPU numbers of threads 0 stay the same whether threads are enabled or not. That’s merely an implementation detail and has no practical impact.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMShj ubah}(h]h ]h"]h$]h&]uh1j hj hhhhhNubjt)}(hhh](j)}(hTSingle Package, Single Core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 h](h)}(hSingle Package, Single Core::h]hSingle Package, Single Core:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMYhj ubh literal_block)}(h4[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0h]h4[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhM[hj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hXSingle Package, Dual Core a) One thread per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 b) Two threads per core:: [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 Alternative enumeration:: [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 nomenclature for CMT systems:: [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 h](h)}(hSingle Package, Dual Coreh]hSingle Package, Dual Core}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM]hj ubjt)}(hhh](j)}(hOne thread per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 h](h)}(hOne thread per core::h]hOne thread per core:}(hj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM_hj. ubj )}(hi[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1h]hi[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1}hj@ sbah}(h]h ]h"]h$]h&]hhuh1j hhhMahj. ubeh}(h]h ]h"]h$]h&]uh1jhj+ ubj)}(hX-Two threads per core:: [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 Alternative enumeration:: [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 nomenclature for CMT systems:: [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 h](h)}(hTwo threads per core::h]hTwo threads per core:}(hjX hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMdhjT ubj )}(h[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 3h]h[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}hjf sbah}(h]h ]h"]h$]h&]hhuh1j hhhMfhjT ubh)}(hAlternative enumeration::h]hAlternative enumeration:}(hjt hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMkhjT ubj )}(h[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 3h]h[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}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhMmhjT ubh)}(h"AMD nomenclature for CMT systems::h]h!AMD nomenclature for CMT systems:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMrhjT ubj )}(hX[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 3h]hX[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}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhMthjT ubeh}(h]h ]h"]h$]h&]uh1jhj+ ubeh}(h]h ]h"]h$]h&]j loweralphaj hj j uh1jshj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhNhNubeh}(h]h ]h"]h$]h&]j j j hj j uh1jshj hhhhhMYubjt)}(hhh]j)}(hXqDual Package, Dual Core a) One thread per core:: [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 b) Two threads per core:: [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 Alternative enumeration:: [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 nomenclature for CMT systems:: [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 7h](h)}(hDual Package, Dual Coreh]hDual Package, Dual Core}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMyhj ubjt)}(hhh](j)}(hOne thread per core:: [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 h](h)}(hOne thread per core::h]hOne thread per core:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM{hj ubj )}(h[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 3h]h[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}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhM}hj ubeh}(h]h ]h"]h$]h&]uh1jhj ubj)}(hXTwo threads per core:: [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 Alternative enumeration:: [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 nomenclature for CMT systems:: [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 7h](h)}(hTwo threads per core::h]hTwo threads per core:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubj )}(hX[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 7h]hX[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}hjsbah}(h]h ]h"]h$]h&]hhuh1j hhhMhjubh)}(hAlternative enumeration::h]hAlternative enumeration:}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubj )}(hX[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 7h]hX[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}hj1sbah}(h]h ]h"]h$]h&]hhuh1j hhhMhjubh)}(h"AMD nomenclature for CMT systems::h]h!AMD nomenclature for CMT systems:}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubj )}(hX([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 7h]hX([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}hjMsbah}(h]h ]h"]h$]h&]hhuh1j hhhMhjubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]j j j hj j uh1jshj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhNhNubah}(h]h ]h"]h$]h&]j j j hj j startKuh1jshj hhhhhMyubeh}(h]system-topology-examplesah ]h"]system topology examplesah$]h&]uh1hhhhhhhhMPubeh}(h] x86-topologyah ]h"] x86 topologyah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jj~jjjjjCj@j j jyjvu nametypes}(jjjjCj jyuh}(j~hjjjjj@jj jFjvj u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]hsystem_message)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "4" (ordinal 4)h]h>Enumerated list start value not ordinal-1: “4” (ordinal 4)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehnjlineKuh1j hj hhhhhMyubatransform_messages] transformerN include_log] decorationNhhub.