Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 以编程方式查找计算机上的内核数_C++_C_Multithreading_Multiplatform - Fatal编程技术网

C++ 以编程方式查找计算机上的内核数

C++ 以编程方式查找计算机上的内核数,c++,c,multithreading,multiplatform,C++,C,Multithreading,Multiplatform,有没有一种方法可以以独立于平台的方式确定一台机器有多少个C/C++内核?如果不存在这样的东西,那么根据平台(Windows/*nix/Mac)确定它怎么样?Windows Server 2003及更高版本允许您利用GetLogicalProcessorInformation函数 在Linux上,您可以读取/proc/cpuinfo文件并计算内核数。您可能无法以独立于平台的方式获取它。Windows您可以获得多个处理器 此功能是C++11标准的一部分 #include <thread>

有没有一种方法可以以独立于平台的方式确定一台机器有多少个C/C++内核?如果不存在这样的东西,那么根据平台(Windows/*nix/Mac)确定它怎么样?

Windows Server 2003及更高版本允许您利用GetLogicalProcessorInformation函数


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

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


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

#include <thread>

unsigned int nthreads = std::thread::hardware_concurrency();
#包括
unsigned int nthreads=std::thread::hardware_concurrency();
对于较旧的编译器,可以使用库

#包括
unsigned int nthreads=boost::thread::hardware_concurrency();

在这两种情况下,
hardware\u concurrency()
根据CPU内核和超线程单元的数量返回硬件能够并发执行的线程数。

在linux上,据我所知,最好的编程方式是使用

sysconf(_SC_NPROCESSORS_CONF)


这些不是标准的,但在我的Linux手册页中。

如果您有汇编语言访问权限,您可以使用CPUID指令获取有关CPU的各种信息。它在操作系统之间是可移植的,不过您需要使用特定于制造商的信息来确定如何找到内核的数量。这是,第11页介绍了AMD规范。

C++11
  • Linux、Solaris、AIX和Mac OS X>=10.4(即Tiger以后的版本)
  • FreeBSD、MacOS X、NetBSD、OpenBSD等。
  • 虹彩
  • Objective-C(Mac OS X>=10.5或iOS)
  • 请注意,“核心数量”可能不是一个特别有用的数字,您可能需要对其进行更多的限定。您希望如何计算多线程CPU,如Intel HT、IBM Power5和Power6,以及最著名的Sun的Niagara/UltraSparc T1和T2?或者更有趣的是,MIPS 1004k具有两级硬件线程(主管级和用户级)。。。更不用说当您进入支持虚拟机监控程序的系统时会发生什么,在这些系统中,硬件可能有几十个CPU,但您的特定操作系统只能看到几个

    您所能期望的最好结果是告诉您的本地OS分区中有多少逻辑处理单元。除非你是一个虚拟机监控程序,否则别想看到真正的机器。目前这一规则的唯一例外是在x86领域,但非虚拟机的终结正在迅速到来…

    在许多平台上都受支持(包括Visual Studio 2005),它提供了

    int omp_get_num_procs();
    

    返回调用时可用的处理器/内核数的函数。

    另一个Windows配方:使用系统范围的环境变量
    处理器数

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

    您也可以在.net中使用WMI,但您将依赖于运行的WMI服务 有时它在本地工作,但在服务器上运行相同的代码时失败。
    我认为这是一个名称空间问题,与您正在读取其值的“名称”有关。

    OSX替代方案:根据文档,前面描述的基于[[NSProcessInfo processInfo]processorCount]的解决方案仅在OSX 10.5.0上可用。对于OS X的早期版本,请使用Carbon函数MPProcessors()

    如果你是一个可可程序员,不要被这是碳的事实吓坏了。您只需要将Carbon框架添加到您的Xcode项目中,MPProcessors()将可用。

    (几乎)c代码中的平台独立函数

    #ifdef _WIN32
    #include <windows.h>
    #elif MACOS
    #include <sys/param.h>
    #include <sys/sysctl.h>
    #else
    #include <unistd.h>
    #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
    }
    
    \ifdef\u WIN32
    #包括
    #埃利夫·马科斯
    #包括
    #包括
    #否则
    #包括
    #恩迪夫
    int getNumCores(){
    #ifdef WIN32
    系统信息系统信息;
    GetSystemInfo(&sysinfo);
    返回sysinfo.dwNumberOfProcessors;
    #埃利夫·马科斯
    int-nm[2];
    尺寸长度=4;
    uint32_t计数;
    nm[0]=CTL_HW;nm[1]=HW_AVAILCPU;
    sysctl(nm,2,&count,&len,NULL,0);
    如果(计数<1){
    nm[1]=HW_NCPU;
    sysctl(nm,2,&count,&len,NULL,0);
    如果(计数<1){count=1;}
    }
    返回计数;
    #否则
    返回sysconf(仅限处理器);
    #恩迪夫
    }
    
    > p>与C++无关,但在Linux上我通常这样做:

    grep processor /proc/cpuinfo | wc -l
    

    适用于bash/perl/python/ruby等脚本语言。

    hwloc(http://www.open-mpi.org/projects/hwloc/)值得一看。虽然需要在代码中集成另一个库,但它可以提供有关处理器的所有信息(内核数、拓扑结构等)

    有关OS X的更多信息:
    sysconf(\u SC\u NPROCESSORS\u ONLN)
    仅适用于版本>=10.5,而不是10.4


    另一种选择是
    HW\u AVAILCPU/sysctl()
    BSD代码,该代码在版本>=10.2上可用。

    在Linux上,仅使用
    \u SC\u处理器可能不安全,因为它不是POSIX标准的一部分,手册中也有很多说明。因此,有一种可能性是,
    \u SC\u 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;
    }
    

    在shell中使用grep的方法相同:

    grep -c ^processor /proc/cpuinfo
    

    对于Win32:

    当GetSystemInfo()获取逻辑处理器的数量时,使用 获取物理处理器的数量。

    Windows(x64和Win32)和C++11 共享单个处理器核心的逻辑处理器组数。(使用,另请参阅)


    请注意,这两种方法都可以很容易地转换为C/C++98/C++03。

    Carefull:超线程处理器说有两种。因此,您还需要查看处理器是否具有超读功能。除了这也将超读或其他SMT解决方案视为更多的核心之外…@Arafangion:超读不是真正的并行执行,而是一种减少上下文切换开销的技术。超线程cpu一次只能执行一个线程,但它可以同时存储两个线程的体系结构状态(寄存器值等)。性能特点如下:
    int numCPU = sysconf(_SC_NPROC_ONLN);
    
    NSUInteger a = [[NSProcessInfo processInfo] processorCount];
    NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];
    
    int omp_get_num_procs();
    
    printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
    
    #ifdef _WIN32
    #include <windows.h>
    #elif MACOS
    #include <sys/param.h>
    #include <sys/sysctl.h>
    #else
    #include <unistd.h>
    #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
    }
    
    grep processor /proc/cpuinfo | wc -l
    
     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).
    
    #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;
    }
    
    #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;
    }
    
    grep -c ^processor /proc/cpuinfo
    
    grep -c ^cpu /proc/stat # subtract 1 from the result
    
    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;
    }
    
    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);
    }