Linux查找超线程核心ID

22

今天上午我一直在尝试找出如何确定处理器 ID 是否为超线程核心,但没有成功。

我希望找到这个信息并使用set_affinity()将进程绑定到超线程线程或非超线程线程以分析其性能。


1
通常情况下,要么所有核心都是超线程的,要么没有一个核心是超线程的。或者我的这个假设是错误的? - knittl
是的,如果启用了超线程(HT),每个物理核心将有2个线程(1个物理+1个HT)。在软件中,两个线程被视为相同,但它们将具有不同的处理器ID(在Linux中)。我想找出哪个ID属于物理线程,哪个属于HT线程。 - Patrick
你的CPU是什么?P4还是Core2或者Corei7或者Atom? - osgx
6个回答

50

我发现了一个简单的技巧来完成我需要的任务。

cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
如果第一个数字与CPU编号相同(在本例中为0),则它是真实核心,否则它是超线程核心。
真实核心示例:
# cat /sys/devices/system/cpu/cpu1/topology/thread_siblings_list
1,13

超线程核心示例

# cat /sys/devices/system/cpu/cpu13/topology/thread_siblings_list
1,13

第二个示例的输出与第一个示例完全相同。但是我们正在检查 cpu13,而第一个数字是 1,因此CPU 13是一核心的超线程。


1
在Xen虚拟化程序上对我无效:ls -l cpu0/topology/,总计为0。----- uname -a: Linux XXXX 2.6.18-128.2.1.4.37.el5xen #1 SMP Sat Apr 9 05:30:32 EDT 2011 i686 i686 i386 GNU/Linux - Joe Casadonte
在Windows上有可能得到某些东西吗? - Tomas Kubes
4
cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | sort | uniq - FreeSoftwareServers

19

我很惊讶,没有人提到lscpu。以下是在一个四核心和超线程启用的单插槽系统上的示例:

$ lscpu -p
# The following is the parsable format, which can be fed to other
# programs. Each different item in every column has an unique ID
# starting from zero.
# CPU,Core,Socket,Node,,L1d,L1i,L2,L3
0,0,0,0,,0,0,0,0
1,1,0,0,,1,1,1,0
2,2,0,0,,2,2,2,0
3,3,0,0,,3,3,3,0
4,0,0,0,,0,0,0,0
5,1,0,0,,1,1,1,0
6,2,0,0,,2,2,2,0
7,3,0,0,,3,3,3,0

这个输出解释了如何解读ID表格;拥有相同核心ID的逻辑CPU ID是兄弟。


但是哪个兄弟是 HT 核心? - Aaron Copley
5
它们是同级的,没有主核心和第二类“超线程”核心。 - Connor Doyle

13

在基本资源方面,HT是对称的(系统模式可能是不对称的)。

因此,如果开启HT,则物理核心的大量资源将在两个线程之间共享。某些额外的硬件被打开以保存两个线程的状态。两个线程对物理核心具有对称访问权。

禁用HT的核心与启用HT的核心之间存在差异;但启用HT的核心的前半部分和后半部分之间没有区别。

在任何时刻,一个HT线程可能使用比另一个线程更多的资源,但这种资源平衡是动态的。如果两个线程都想使用相同的资源,CPU将尽力平衡线程,并根据自己的意愿进行平衡。您只能在一个线程中执行“rep nop”或“pause”,以便CPU为其他线程提供更多资源。

我希望找出这些信息并使用set_affinity()将进程绑定到超线程线程或非超线程线程以分析其性能。

好的,实际上您可以在不知道事实的情况下测量性能。只需在系统中唯一的线程绑定到CPU0时进行分析;并且在将其绑定到CPU1时重复该操作。我认为结果几乎相同(如果操作系统将某些中断绑定到CPU0,则可能会生成噪音;因此在测试时尝试降低中断数量,并尽量使用CPU2和CPU3)。

PS

Agner(他是x86方面的专家)建议在不使用HT的情况下(但在BIOS中启用了HT)使用偶数核心:

如果检测到超线程,则锁定进程仅使用逻辑处理器的偶数编号。这将使每个处理器核心中的两个线程中的一个处于闲置状态,因此不会争用资源。

PPS 关于新重生的HT(不是P4,而是Nehalem和Sandy) - 基于Agner对微架构的研究

Sandy Bridge新的瓶颈包括以下内容: ... 5. 线程之间的资源共享。当启用超线程技术时,许多关键资源在核心的两个线程之间共享。如果多个线程依赖于相同的执行资源,则关闭超线程可能是明智的选择。

...

半路解决方案在NetBurst中被引入,并在Nehalem和Sandy Bridge中再次出现,称为超线程技术。超线程处理器具有共享同一执行核心的两个逻辑处理器。如果两个线程竞争相同的资源,则优势有限,但如果性能受到其他方面(如内存访问)的限制,则超线程可能非常有利。

...

Intel和AMD都正在开发混合解决方案,其中一些或所有执行单元在两个处理器核心之间共享(Intel术语中的超线程)。
PPPS:Intel优化手册列出了第二代HT中的资源共享:(第93页,此列表适用于Nehalem,但在Sandy部分没有更改)

...

更深的缓冲和增强的资源共享/分区策略:
  • — 用于HT操作的复制资源:寄存器状态,重命名返回堆栈缓冲区,大页面ITLB //我的注释:此硬件有2组
  • — 用于HT操作的分割资源:加载缓冲区,存储缓冲区,重新排序缓冲区,小页面ITLB在两个逻辑处理器之间静态分配。//我的注释:此硬件只有一组;它在两个HT虚拟核心中静态地分为两半
  • — 在HT操作期间竞争共享资源:预约站,
  • 缓存层次结构,填充缓冲区,DTLB0和STLB均被使用。 // 注释: 单个集合,但不是均分。CPU将动态重新划分资源。
  • - 在HT操作期间交替进行:前端操作通常在两个逻辑处理器之间交替进行,以确保公平性。 // 注释: 只有单个前端(指令解码器),因此线程将按顺序解码:1、2、1、2。
  • - HT无法感知的资源:执行单元。 // 注释: 存在实际的硬件设备来执行计算和内存访问。只有单个集合。如果其中一个线程能够使用大量的执行单元,并且它具有较低数量的内存等待,则它将消耗所有执行单元,并且第二个线程的性能将较低(但HT有时会切换到第二个线程。频率多久???)。如果两个线程都没有经过重度优化和/或存在内存等待,则执行单元将在两个线程之间分配。

页面112上还有图片(图2-13),显示两个逻辑核心均为对称。

由于HT技术而产生的性能潜力是由于:

  • •操作系统和用户程序可以安排进程或线程在每个物理处理器的逻辑处理器上同时执行
  • •能够以比仅有单个线程消耗执行资源时更高的水平使用芯片内执行资源;更高水平的资源利用率可以导致更高的系统吞吐量

虽然两个程序或两个线程发起的指令在执行核心和内存层次结构中不一定按程序顺序同时执行,但前端和后端包含多个选择点,以在来自两个逻辑处理器的指令之间进行选择。所有选择点都会交替使用两个逻辑处理器,除非一个逻辑处理器无法利用流水线阶段。在这种情况下,另一个逻辑处理器将完全使用流水线阶段的每个时钟周期。逻辑处理器可能不使用流水线阶段的原因包括缓存未命中、分支预测错误和指令依赖性等。


2
你说了很多话,却什么也没说。 - suprjami
它被标记为正确答案,请向上滚动并查找大绿色勾号。 - suprjami
1
这是一个非常全面的答案。谢谢。 - DAG

5

有一个通用的(Linux/Windows)和便携式的硬件拓扑侦测器,被 OpenMPI 项目称为 hwloc。你可以使用它,因为 Linux 可以使用不同的 HT 核心编号规则,我们无法确定是偶数 / 奇数还是 y 和 y+8 编号规则。

hwloc 的主页: http://www.open-mpi.org/projects/hwloc/

下载页面: http://www.open-mpi.org/software/hwloc/v1.10/

描述:

便携式硬件拓扑(hwloc)软件包提供了现代架构的分层拓扑的可移植抽象(跨操作系统、版本、架构等)。包括 NUMA 内存节点、插座、共享缓存、核心和同时多线程。它还收集各种系统属性,如缓存和内存信息以及 I/O 设备的位置,例如网络接口、InfiniBand HCAs 或 GPUs。它主要旨在帮助应用程序收集有关现代计算硬件的信息,以便相应地高效地利用它。

它有 lstopo 命令,可以以图形形式获取硬件拓扑,如下所示:

 ubuntu$ sudo apt-get hwloc
 ubuntu$ lstopo

lstopo from hwloc (OpenMPI) - output example

或者以文本形式:

 ubuntu$ sudo apt-get hwloc-nox
 ubuntu$ lstopo --of console

我们可以将物理核心视为Core L#x,每个物理核心有两个逻辑核心PU L#yPU L#y+8
Machine (16GB)
  Socket L#0 + L3 L#0 (4096KB)
    L2 L#0 (1024KB) + L1 L#0 (16KB) + Core L#0
      PU L#0 (P#0)
      PU L#1 (P#8)
    L2 L#1 (1024KB) + L1 L#1 (16KB) + Core L#1
      PU L#2 (P#4)
      PU L#3 (P#12)
  Socket L#1 + L3 L#1 (4096KB)
    L2 L#2 (1024KB) + L1 L#2 (16KB) + Core L#2
      PU L#4 (P#1)
      PU L#5 (P#9)
    L2 L#3 (1024KB) + L1 L#3 (16KB) + Core L#3
      PU L#6 (P#5)
      PU L#7 (P#13)
  Socket L#2 + L3 L#2 (4096KB)
    L2 L#4 (1024KB) + L1 L#4 (16KB) + Core L#4
      PU L#8 (P#2)
      PU L#9 (P#10)
    L2 L#5 (1024KB) + L1 L#5 (16KB) + Core L#5
      PU L#10 (P#6)
      PU L#11 (P#14)
  Socket L#3 + L3 L#3 (4096KB)
    L2 L#6 (1024KB) + L1 L#6 (16KB) + Core L#6
      PU L#12 (P#3)
      PU L#13 (P#11)
    L2 L#7 (1024KB) + L1 L#7 (16KB) + Core L#7
      PU L#14 (P#7)
      PU L#15 (P#15)

5

在bash中获取CPU核心的超线程同级别的简单方法:

cat $(find /sys/devices/system/cpu -regex ".*cpu[0-9]+/topology/thread_siblings_list") | sort -n | uniq

还有一个命令是lscpu -e,它可以提供与核心和CPU相关的信息:

CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ    MINMHZ
0   0    0      0    0:0:0:0       yes    4100.0000 400.0000
1   0    0      1    1:1:1:0       yes    4100.0000 400.0000
2   0    0      2    2:2:2:0       yes    4100.0000 400.0000
3   0    0      3    3:3:3:0       yes    4100.0000 400.0000
4   0    0      0    0:0:0:0       yes    4100.0000 400.0000
5   0    0      1    1:1:1:0       yes    4100.0000 400.0000
6   0    0      2    2:2:2:0       yes    4100.0000 400.0000
7   0    0      3    3:3:3:0       yes    4100.0000 400.0000

1
我尝试通过比较HT核心的温度和负载来验证信息。

enter image description here


2
你的方法很奇怪,可能不起作用。尝试使用hwloc:http://www.open-mpi.org/projects/hwloc/ 它有win32和win64变体。 - osgx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接