有没有办法以独立于平台的方式确定机器有多少来自C/C++的内核?如果不存在这样的事情,那么每个平台确定它(Windows/*nix/Mac)呢?
//may return 0 when not able to detect unsigned concurentThreadsSupported = std::thread::hardware_concurrency();
参考:std :: thread :: hardware_concurrency
在C++ 11之前的C++中,没有可移植的方式.相反,您需要使用以下一种或多种方法(由适当的#ifdef
行保护):
SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); int numCPU = sysinfo.dwNumberOfProcessors;
int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
int mib[4]; int numCPU; std::size_t len = sizeof(numCPU); /* set the mib for hw.ncpu */ mib[0] = CTL_HW; mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; /* get the number of CPUs from the system */ sysctl(mib, 2, &numCPU, &len, NULL, 0); if (numCPU < 1) { mib[1] = HW_NCPU; sysctl(mib, 2, &numCPU, &len, NULL, 0); if (numCPU < 1) numCPU = 1; }
int numCPU = mpctl(MPC_GETNUMSPUS, NULL, NULL);
int numCPU = sysconf(_SC_NPROC_ONLN);
NSUInteger a = [[NSProcessInfo processInfo] processorCount]; NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];
此功能是C++ 11标准的一部分.
#includeunsigned int nthreads = std::thread::hardware_concurrency();
对于较旧的编译器,您可以使用Boost.Thread库.
#includeunsigned int nthreads = boost::thread::hardware_concurrency();
在任何一种情况下,hardware_concurrency()
都会根据CPU内核和超线程单元的数量返回硬件能够并发执行的线程数.
许多平台(包括Visual Studio 2005)都支持OpenMP,它提供了一个
int omp_get_num_procs();
返回调用时可用处理器/核心数的函数.
如果您具有汇编语言访问权限,则可以使用CPUID指令获取有关CPU的各种信息.它可以在操作系统之间移植,但您需要使用制造商特定的信息来确定如何查找核心数.下面是描述如何做到这一点英特尔芯片的文档,以及第11页这一个介绍AMD规范.
(几乎)c-code中的平台无关功能
#ifdef _WIN32 #include#elif MACOS #include #include #else #include #endif int getNumCores() { #ifdef WIN32 SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; #elif MACOS int nm[2]; size_t len = 4; uint32_t count; nm[0] = CTL_HW; nm[1] = HW_AVAILCPU; sysctl(nm, 2, &count, &len, NULL, 0); if(count < 1) { nm[1] = HW_NCPU; sysctl(nm, 2, &count, &len, NULL, 0); if(count < 1) { count = 1; } } return count; #else return sysconf(_SC_NPROCESSORS_ONLN); #endif }
在Linux上,您可以读取/ proc/cpuinfo文件并计算内核.
请注意,"核心数"可能不是特别有用的数字,您可能需要更多地限定它.您想如何计算多线程CPU,例如Intel HT,IBM Power5和Power6,以及最着名的Sun的Niagara/UltraSparc T1和T2?或者更有趣的是,MIPS 1004k具有两级硬件线程(管理员和用户级)...更不用说当你进入虚拟机管理程序支持的系统时会发生什么,其中硬件可能有几十个CPU而你的特定操作系统只看到一些.
您可以期望的最好的方法是告诉您在本地操作系统分区中拥有的逻辑处理单元的数量.除非你是一个虚拟机管理程序,否则忘了看真机.今天这个规则的唯一例外是在x86领域,但非虚拟机的终结正在快速发展......
您可能无法以独立于平台的方式获取它.Windows获得多个处理器.
Win32系统信息
还有一个Windows配方:使用系统范围的环境变量NUMBER_OF_PROCESSORS
:
printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
共享单个处理器核心的逻辑处理器组的数量.(使用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
IMHO 的实现远非琐碎(即"使用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.
有关OS X的更多信息:sysconf(_SC_NPROCESSORS_ONLN)
仅提供版本> = 10.5,而不是10.4.
另一种方法是HW_AVAILCPU/sysctl()
BSD代码,可在版本> = 10.2时使用.