有没有一种方法可以以平台无关的方式确定一台机器有多少个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。
其他回答
OpenMP在许多平台(包括Visual Studio 2005)上都得到了支持,并且它提供了一种支持
int omp_get_num_procs();
函数返回调用时可用的处理器/核数。
#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的实现。
Note that "number of cores" might not be a particularly useful number, you might have to qualify it a bit more. How do you want to count multi-threaded CPUs such as Intel HT, IBM Power5 and Power6, and most famously, Sun's Niagara/UltraSparc T1 and T2? Or even more interesting, the MIPS 1004k with its two levels of hardware threading (supervisor AND user-level)... Not to mention what happens when you move into hypervisor-supported systems where the hardware might have tens of CPUs but your particular OS only sees a few.
最好的情况是告诉您在本地OS分区中拥有的逻辑处理单元的数量。除非您是管理程序,否则不要考虑看到真正的机器。今天这个规则唯一的例外是在x86领域,但非虚拟机的末日很快就会到来……
这个功能是c++ 11标准的一部分。
#include <thread>
unsigned int nthreads = std::thread::hardware_concurrency();
对于较老的编译器,可以使用Boost。线程库。
#include <boost/thread.hpp>
unsigned int nthreads = boost::thread::hardware_concurrency();
在任何一种情况下,hardware_concurrency()都会根据CPU内核和超线程单元的数量返回硬件能够并发执行的线程数。
在Linux上,使用_SC_NPROCESSORS_ONLN可能是不安全的,因为它不是POSIX标准的一部分,sysconf手册也有同样的说明。所以有可能_SC_NPROCESSORS_ONLN不存在:
These values also exist, but may not be standard.
[...]
- _SC_NPROCESSORS_CONF
The number of processors configured.
- _SC_NPROCESSORS_ONLN
The number of processors currently online (available).
一个简单的方法是读取/proc/stat或/proc/cpuinfo并计算它们:
#include<unistd.h>
#include<stdio.h>
int main(void)
{
char str[256];
int procCount = -1; // to offset for the first entry
FILE *fp;
if( (fp = fopen("/proc/stat", "r")) )
{
while(fgets(str, sizeof str, fp))
if( !memcmp(str, "cpu", 3) ) procCount++;
}
if ( procCount == -1)
{
printf("Unable to get proc count. Defaulting to 2");
procCount=2;
}
printf("Proc Count:%d\n", procCount);
return 0;
}
使用 /proc/cpuinfo:
#include<unistd.h>
#include<stdio.h>
int main(void)
{
char str[256];
int procCount = 0;
FILE *fp;
if( (fp = fopen("/proc/cpuinfo", "r")) )
{
while(fgets(str, sizeof str, fp))
if( !memcmp(str, "processor", 9) ) procCount++;
}
if ( !procCount )
{
printf("Unable to get proc count. Defaulting to 2");
procCount=2;
}
printf("Proc Count:%d\n", procCount);
return 0;
}
同样的方法在shell中使用grep:
grep -c ^processor /proc/cpuinfo
Or
grep -c ^cpu /proc/stat # subtract 1 from the result
推荐文章
- decltype(auto)的一些用途是什么?
- Shared_ptr转换为数组:应该使用它吗?
- 使用C返回一个数组
- Printf与std::字符串?
- 禁用复制构造函数
- 自动化invokerrequired代码模式
- 只接受特定类型的c++模板
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 为什么pthreads的条件变量函数需要互斥?
- c++ 11中的递归lambda函数
- 在c++中指针使用NULL或0(零)吗?
- 在c++中,如何将int值附加到字符串中?
- __FILE__宏显示完整路径