当前位置:  开发笔记 > 编程语言 > 正文

以编程方式查找计算机上的核心数

如何解决《以编程方式查找计算机上的核心数》经验,为你挑选了11个好方法。

有没有办法以独立于平台的方式确定机器有多少来自C/C++的内核?如果不存在这样的事情,那么每个平台确定它(Windows/*nix/Mac)呢?



1> paxos1977..:
C++ 11
//may return 0 when not able to detect
unsigned concurentThreadsSupported = std::thread::hardware_concurrency();

参考:std :: thread :: hardware_concurrency


在C++ 11之前的C++中,没有可移植的方式.相反,您需要使用以下一种或多种方法(由适当的#ifdef行保护):

Win32的

SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
int numCPU = sysinfo.dwNumberOfProcessors;

Linux,Solaris,AIX和Mac OS X> = 10.4(即Tiger以后)

int numCPU = sysconf(_SC_NPROCESSORS_ONLN);

FreeBSD,MacOS X,NetBSD,OpenBSD等

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;
}

HPUX

int numCPU = mpctl(MPC_GETNUMSPUS, NULL, NULL);

IRIX

int numCPU = sysconf(_SC_NPROC_ONLN);

Objective-C(Mac OS X> = 10.5或iOS)

NSUInteger a = [[NSProcessInfo processInfo] processorCount];
NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];


@mcandre:这是留给读者的练习.如果我正在实现,我可能会使用模板策略方法,其中策略是在预处理器指令中定义的.或者......你可以使用boost thread :: hardware_concurrency().
作为澄清的一点,Win32解决方案返回核心总数(要求的内容)而不是物理CPU总数.
有几点需要注意.在OS X上不推荐使用`HW_NCPU`.在Windows上,`GetSystemInfo`仅在系统有32个或更少逻辑处理器时才有用,对于具有32个以上逻辑处理器的系统使用`GetLogicalProcessorInformation`.

2> Ferruccio..:

此功能是C++ 11标准的一部分.

#include 

unsigned int nthreads = std::thread::hardware_concurrency();

对于较旧的编译器,您可以使用Boost.Thread库.

#include 

unsigned int nthreads = boost::thread::hardware_concurrency();

在任何一种情况下,hardware_concurrency()都会根据CPU内核和超线程单元的数量返回硬件能够并发执行的线程数.



3> macbirdie..:

许多平台(包括Visual Studio 2005)都支持OpenMP,它提供了一个

int omp_get_num_procs();

返回调用时可用处理器/核心数的函数.


此函数返回调用进程可用的CPU数.这不是最常见的用例吗?如果您无法在代码中利用它们,那么CPU硬件核心的实际数量与您无关.
这将返回逻辑CPU的数量,而不是核心(物理CPU)的数量。

4> Head Geek..:

如果您具有汇编语言访问权限,则可以使用CPUID指令获取有关CPU的各种信息.它可以在操作系统之间移植,但您需要使用制造商特定的信息来确定如何查找核心数.下面是描述如何做到这一点英特尔芯片的文档,以及第11页这一个介绍AMD规范.


它可能已被低估,因为该问题被标记为C++,并且此答案不适用于在非x86体系结构(ARM,PPC等)上运行C++的系统.我不是说这是一个很好的理由拒绝回答,只是一种可能性.
如果您使用CPUID检测Intel处理器上的HyperThreading,则此方法的一个缺陷就是如此.我在我的笔记本电脑上遇到了这个问题:虽然我放入机器的CPU支持HyperThreading(当然,报告它通过CPUID报告),但BIOS却没有.因此,您不应仅仅尝试从CPUID读取中使用HT功能.由于您无法查询BIOS有关HT支持的信息(我没见过),因此应该查询操作系统以获取逻辑处理器数量.

5> 小智..:

(几乎)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
}



6> JesperE..:

在Linux上,您可以读取/ proc/cpuinfo文件并计算内核.


@Arafangion:超线程并不是真正的并行执行,它是一种减少上下文切换开销的技术.超线程cpu一次只能*执行*一个线程,但它可以同时存储两个线程的架构状态(寄存器值等).性能特征与具有两个核心非常不同.
@Wim:这不完全正确.具有超线程的CPU通常具有多个ALU,并且每个周期可以分派多个指令.如果由于数据依赖性和停顿,并非所有ALU都可以由一个线程保持忙,那么这些ALU将用于同时执行第二个硬件线程.

7> jakobengblom..:

请注意,"核心数"可能不是特别有用的数字,您可能需要更多地限定它.您想如何计算多线程CPU,例如Intel HT,IBM Power5和Power6,以及最着名的Sun的Niagara/UltraSparc T1和T2?或者更有趣的是,MIPS 1004k具有两级硬件线程(管理员和用户级)...更不用说当你进入虚拟机管理程序支持的系统时会发生什么,其中硬件可能有几十个CPU而你的特定操作系统只看到一些.

您可以期望的最好的方法是告诉您在本地操作系统分区中拥有的逻辑处理单元的数量.除非你是一个虚拟机管理程序,否则忘了看真机.今天这个规则的唯一例外是在x86领域,但非虚拟机的终结正在快速发展......



8> Ken..:

您可能无法以独立于平台的方式获取它.Windows获得多个处理器.

Win32系统信息



9> Constantin..:

还有一个Windows配方:使用系统范围的环境变量NUMBER_OF_PROCESSORS:

printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));



10> Matthias..:

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;
}

请注意,NumberOfPhysicalCoresIMHO 的实现远非琐碎(即"使用GetLogicalProcessorInformationGetLogicalProcessorInformationEx").相反,如果在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.



11> 小智..:

有关OS X的更多信息:sysconf(_SC_NPROCESSORS_ONLN)仅提供版本> = 10.5,而不是10.4.

另一种方法是HW_AVAILCPU/sysctl()BSD代码,可在版本> = 10.2时使用.

推荐阅读
虎仔球妈_459
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有