以编程方式获取Windows上硬件线程数的可靠方法
Reliable way to programmatically get the number of hardware threads on Windows
我正在努力寻找一种可靠的方法来获得Windows上硬件线程的数量。我在一台双CPU Intel Xeon E5-2699 v3@2.30GHz的机器上运行Windows 7 Professional SP1 64位,总共有36个内核和72个线程。我尝试了不同的方法来获得内核的数量,我发现在32位或64位进程中,似乎只有两种方法能准确工作。以下是我的结果:
+------------------------------------------------+----------------+----------------+|方法|32位进程|64位进程|+------------------------------------------------+----------------+----------------+|GetSystemInfo->dwNumberOfProcessors|32|36||GetNativeSystemInfo->dwNumberOfProcessors|36|36||获取逻辑处理器信息|36|36||GetProcessAffinityMask.ProcessAffinity Mask|32|32||GetProcessAffinityMask.SystemAffinityMusk|32|32||omp_get_num_procs|32|36||getenv("NUMBER_OF_PROCESSORS"(|36|36||GetActiveProcessorCount(ALL_PROCESSOR_GROUPS(|64|72||GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS(|64|72||boost::thread::hardware_concurrency((|32|36||性能计数器API | 36 | 36||WMI|72|72||硬件\描述\系统\中央处理器|72|72|+------------------------------------------------+----------------+----------------+
我不解释为什么所有这些函数都返回不同的值。对我来说,唯一可靠的两种方法要么是使用WMI(但相当复杂(,要么只是在Windows注册表中读取以下项:硬件\描述\系统\中央处理器。
你觉得怎么样?您确认WMI和注册表项方法是唯一可靠的方法吗?
提前感谢
您需要的API函数是GetLogicalProcessorInformationEx
。由于您有超过64个处理器,因此会对您的处理器进行分组。GetLogicalProcessorInformation
仅报告当前分配线程的处理器组中的处理器。您需要使用GetLogicalProcessorInformationEx
来克服这个限制。
文件上写着:
在具有64个以上逻辑处理器的系统上,GetLogicalProcessorInformation函数检索调用线程当前分配到的处理器组中的处理器的逻辑处理器信息。使用GetLogicalProcessorInformationEx函数检索有关系统上所有处理器组中处理器的信息。
代码为的延迟回答
size_t myHardwareConcurrency(){
size_t concurrency=0;
DWORD length=0;
if(GetLogicalProcessorInformationEx(RelationAll,nullptr,&length)!=FALSE){
return concurrency;}
if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER){
return concurrency;}
std::unique_ptr<void,void(*)(void*)>buffer(std::malloc(length),std::free);
if(!buffer){
return concurrency;}
unsigned char*mem=reinterpret_cast<unsigned char*>(buffer.get());
if(GetLogicalProcessorInformationEx(RelationAll,reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem),&length)==false){
return concurrency;}
for(DWORD i=0;i<length;){
auto*proc=reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem+i);
if(proc->Relationship==RelationProcessorCore){
for(WORD group=0;group<proc->Processor.GroupCount;++group){
for(KAFFINITY mask=proc->Processor.GroupMask[group].Mask;mask!=0;mask>>=1){
concurrency+=mask&1;}}}
i+=proc->Size;}
return concurrency;}
它在我的双Xeon gold 6154上运行,带有Windows 64位系统(2个进程*18个内核/proc*2个线程/core=72个线程(。对于32位处理和64位处理,结果都是72。
不过,我无法访问带有32位Windows的系统。
如果出现错误,它会像std::thread::hardware_concurrency
一样返回零。
您可以使用CPUID指令直接查询处理器(独立于平台,但由于某些编译器不能再在MSVC中执行内联asm,因此需要使用不同的函数才能访问它(。唯一的缺点是,几年前,英特尔和AMD对该指令的处理方式有所不同,您需要做大量工作来确保正确读取信息。事实上,您不仅可以获得核心计数,还可以获得各种处理器拓扑信息。如果您使用的是虚拟机环境,则不确定它在虚拟机中是如何工作的。
- 方法重写线程C++中的概念
- 使用基类中的派生方法运行线程,而无需使用模板
- 将线程中的数据存储到全局容器的最佳方法?
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 如何将带有参数的方法传递给线程以执行?
- C++ POCO - 如何在不使用 run() 方法的情况下启动线程池上的线程?
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- C++中的多线程:连接线程的正确方法
- 使用包含互斥锁的类的方法实例化 cpp11 线程
- 如何在JNI中从线程内部调用JAVA方法
- 如何从另一个线程调用颤振引擎方法
- 在另一个线程上发出 QObject 信号的正确方法?
- 在C++线程内实现多个计时器的最安全方法
- C++ std::线程调用方法,从对象原因到调用此类的析构函数
- 将指针传递到另一个线程的正确方法
- 在另一个 QThread 上运行成员方法时,无法将事件发送到其他线程拥有的对象
- 解决方法:QPixmap:在GUI线程之外使用pixmap是不安全的
- CPP:如何使用需要指针的方法创建线程
- 初始化线程的正确方法
- 从另一个线程更新QT小部件的一种详细方法