有没有一种方法可以以平台无关的方式确定一台机器有多少个C/ c++内核?如果不存在这样的东西,如何确定每个平台(Windows/*nix/Mac)?
当前回答
Windows (x64和Win32)和c++ 11
共享单个处理器核心的逻辑处理器组的数目。(使用GetLogicalProcessorInformationEx,参见GetLogicalProcessorInformation)
size_t NumberOfPhysicalCores() noexcept {
DWORD length = 0;
const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length);
assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
std::unique_ptr< uint8_t[] > buffer(new uint8_t[length]);
const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info =
reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get());
const BOOL result_second = GetLogicalProcessorInformationEx(RelationProcessorCore, info, &length);
assert(result_second != FALSE);
size_t nb_physical_cores = 0;
size_t offset = 0;
do {
const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX current_info =
reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get() + offset);
offset += current_info->Size;
++nb_physical_cores;
} while (offset < length);
return nb_physical_cores;
}
注意,NumberOfPhysicalCores的实现在我看来远非简单(例如:"使用GetLogicalProcessorInformation或GetLogicalProcessorInformationEx")。相反,如果阅读MSDN的文档(显式地为GetLogicalProcessorInformation提供,隐式地为GetLogicalProcessorInformationEx提供),就会发现这是相当微妙的。
逻辑处理器的数量。(使用GetSystemInfo)
size_t NumberOfSystemCores() noexcept {
SYSTEM_INFO system_info;
ZeroMemory(&system_info, sizeof(system_info));
GetSystemInfo(&system_info);
return static_cast< size_t >(system_info.dwNumberOfProcessors);
}
注意,这两种方法都可以很容易地转换为C/ c++ 98/ c++ 03。
其他回答
Windows Server 2003及以后版本允许您利用GetLogicalProcessorInformation函数
http://msdn.microsoft.com/en-us/library/ms683194.aspx
在Linux上,可以读取/proc/cpuinfo文件并计算核数。
#include <stdint.h>
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/sysctl.h>
uint32_t num_physical_cores(void)
{
uint32_t num_cores = 0;
size_t num_cores_len = sizeof(num_cores);
sysctlbyname("hw.physicalcpu", &num_cores, &num_cores_len, 0, 0);
return num_cores;
}
#elif defined(__linux__)
#include <unistd.h>
#include <stdio.h>
uint32_t num_physical_cores(void)
{
uint32_t lcores = 0, tsibs = 0;
char buff[32];
char path[64];
for (lcores = 0;;lcores++) {
FILE *cpu;
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%u/topology/thread_siblings_list", lcores);
cpu = fopen(path, "r");
if (!cpu) break;
while (fscanf(cpu, "%[0-9]", buff)) {
tsibs++;
if (fgetc(cpu) != ',') break;
}
fclose(cpu);
}
return lcores / (tsibs / lcores);
}
#else
#error Unrecognized operating system
#endif
这将返回系统上的物理核数。这与大多数答案提供的逻辑核数量不同。如果您希望确定一个不执行阻塞I/O且不休眠的线程池的大小,那么您希望使用物理内核的数量,而不是逻辑(超线程)内核的数量。
这个答案只提供Linux和bsd的实现。
与c++无关,但在Linux上我通常这样做:
grep processor /proc/cpuinfo | wc -l
适用于bash/perl/python/ruby等脚本语言。
Win32:
GetSystemInfo()获取逻辑处理器的数量,使用 GetLogicalProcessorInformationEx () 来获取物理处理器的数量。