std::thread::hardware_concurrency() 返回操作系统报告的逻辑核心数(含超线程),如i7-10875h返回16;它不提供物理核信息,可能返回0,仅适用于线程池初始化,不适用于numa绑核或功耗控制。

std::thread::hardware_concurrency() 只返回逻辑核心数,无法区分物理/逻辑 —— 这是它最常被误用的地方。 你需要根据平台调用底层 API 或系统接口才能拿到物理核心数。
std::thread::hardware_concurrency() 返回什么?
它返回操作系统报告的“可并发执行的硬件线程数”,即逻辑核心数(含超线程)。比如 i7-10875H 有 8 物理核、16 逻辑核,该函数大概率返回 16。它不提供物理核信息,也不保证非零 —— 某些嵌入式或容器环境会返回 0。
- 跨平台但语义模糊:C++ 标准只要求它“尽力返回合理值”,没定义“物理”或“逻辑”
- 不能用于判断是否启用超线程,也不能替代物理核感知的调度策略
- 若你只做线程池大小初始化,它够用;若要做 NUMA 绑核或功耗控制,必须往下走
Windows 上怎么拿物理核心数?
Win10 1607+ 推荐用 GetLogicalProcessorInformation 解析缓存拓扑,但更简单可靠的是查 Win32_Processor WMI 类,或直接用 GetActiveProcessorCount 配合 LOGICAL_PROCESSOR_RELATIONSHIP::RelationProcessorCore。
-
GetSystemInfo的dwNumberOfProcessors是逻辑数,不是物理数 - 用
GetLogicalProcessorInformation时,需遍历所有PROCESSOR_RELATIONSHIP结构,统计Relationship == RelationProcessorCore的组数(每组对应一个物理核) - 注意:同一物理核上的多个逻辑处理器共享一个
GroupMask,但Group字段可能跨 NUMA 节点,别只数结构体个数
Linux/macOS 怎么区分物理与逻辑核心?
Linux 下优先用 sysconf(_SC_NPROCESSORS_ONLN) 得逻辑数;物理核得查 /sys/devices/system/cpu/cpu*/topology/core_id 去重,或用 lscpu 的解析逻辑(但代码里别直接 popen)。
- macOS 必须用
sysctl:sysctl -n hw.physicalcpu→ 物理核,hw.logicalcpu→ 逻辑核;传参时目标指针类型必须是int*,长度为sizeof(int) - Linux 的
sysconf(_SC_NPROCESSORS_CONF)和_SC_NPROCESSORS_ONLN都是逻辑维度,不反映物理结构 -
get_nprocs()和get_nprocs_conf()同样只返回逻辑数,别被函数名误导
为什么物理核心数难获取?
因为操作系统抽象层有意隐藏了微架构细节 —— 物理核数不是稳定 ABI,不同 CPU(如 AMD CCD vs Intel hybrid)上报方式差异大,且热插拔、cgroup 限核、VM 虚拟化都会干扰探测结果。
真正可靠的方案往往要组合多个来源:读 /proc/cpuinfo 的 cpu cores 字段(仅在 non-SMT 系统准确)、比对 core id 与 physical id、再 fallback 到 sysconf + heuristics。多数生产级库(如 hwloc)都这么干。你自己写时,别指望单个 API 一招鲜。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











