hardware_concurrency() 返回值是物理核数还是虚拟核数

前言

早上面试的时候被问到项目中多线程的实现方式以及线程池中线程数量的该如何确定?我回答了 hardware_concurrency(),接着被追问 hardware_concurrency() 返回值是物理核数还是虚拟核数?我说名字里有 hardware,应该是物理核数,没想到猜错了哈哈哈哈哈面试官说是虚拟核数.

hardware_concurrency()

cplusplus 上对于 hardware_concurrency() 的描述:

  • Returns the number of hardware thread contexts.
  • The interpretation of this value is system- and implementation- specific, and may not be exact, but just an approximation.
  • Note that this does not need to match the actual number of processors or cores available in the system: A system can support multiple threads per processing unit, or restrict the access to its resources to the program.
  • If this value is not computable or well defined, the function returns 0.

第一点提到其返回值是硬件线程上下文的数量,第三点提到该返回值可能并不与真是的处理器或者核数相一致(因为系统可以在一个处理单元上运行多个线程)。

StackOverflow 上有一个问题提到这个方法,其中有一个回答:

Even when hardware_concurrency is implemented, it cannot be relied as a direct mapping to the number of cores. This is what the standard says it returns - The number of hardware thread contexts. And goes on to state - This value should only be considered to be a hint If your machine has hyperthreading enabled, it’s entirely possible the value returned will be 2x the number of cores. If you want a reliable answer, you’ll need to use whatever facilities your OS provides. – PraetorianJan 15 '15 at 19:21

说到该返回值 cannot be relied as a direct mapping to the number of core,也就是不直接与(物理)核数对应,如果开启了超线程技术,那么返回值将会是(物理)核数的 2 倍,也就是虚拟核数。

物理核、虚拟核

实际上,核的概念分为 物理核(Physical Core) 和 逻辑核(Logical Core),在我们说多核处理器的时候,其实是有二义性的——我们不知道讲的是多个 物理核 还是 逻辑核 。

  • 物理核
    • 物理上、真实存在的 核(Core),可以在硬件层面上看到数量的 核(Core)
  • 逻辑核
    • 理解上,只是逻辑上存在的 核(Core) 无法通过硬件层面判断出数量
    • 实际上,基于 Intel 的 超线程技术(Hyper-Threading) 将一个物理核拆分成两个逻辑核,更加高效地执行 CPU 指令以及利用 L1 缓存

除此之外,无论是 Linux / Mac 还是 Windows 的资源管理器,我们看到的数量都是逻辑核的数量,计算公式大致如下:

  • 物理核数 = 物理核数(Dual Core = 双核 / Quad-Core = 四核)
  • 逻辑核数 = 物理核数 or 物理核数 x 2(开启了 HT)

超线程 Hyper-Threading

有时候我们谈到双核四线程的时候,实质上谈到的就是超线程技术(Hyper-Threading),超线程技术是一种硬件创新,允许一个以上的线程运行在每个核心,更多的线程意味着可以并行地完成更多的工作。

  • How does Hyper-Threading work? When Intel® Hyper-Threading Technology is active, the CPU exposes two execution contexts per physical core. This means that one physical core now works like two “logical cores” that can handle different software threads. The ten-core Intel® Core™ i9-10900K processor, for example, has 20 threads when Hyper-Threading is enabled.
  • Two logical cores can work through tasks more efficiently than a traditional single-threaded core. By taking advantage of idle time when the core would formerly be waiting for other tasks to complete, Intel® Hyper-Threading Technology improves CPU throughput (by up to 30% in server applications3).

单核双线程

一个支持超线程技术的 CPU 物理核心,里面会有两套独立的寄存器但共用剩下的计算单元和缓存,比如 ALU(算术逻辑单元) 和 L1 / L2 缓存。反之,若不支持超线程的 CPU 物理核心中只会有一套寄存器,也能通过这个图直观的理解超线程带来的一些效率提升。从一个运行在开启了超线程的 CPU 的操作系统的角度来看,此时它管理着两个 CPU(逻辑上的),这两个逻辑 cpu 在同一个物理 cpu 上运行。 不过这样并不会产生两倍于传统处理器的处理能力,也不可能提供完全的并行处理能力,因为它们不能作为两个完整的独立的处理器来执行。

多核多线程

四核八线程就是将四个单核两线程的物理核心装在一个芯片(Chip) 上。

在 Windows 系统上开启/关闭虚拟化(Hyper-V)

左图是在我的电脑上开启了 Hyper-V,右图是女朋友的电脑,没有开启 Hyper-V。同样是四个内核,开了 Hyper-V 后资源管理器中显示的逻辑处理器数量翻倍了。

开启虚拟化 关闭虚拟化

参考