Программно найти количество ядер на машине - PullRequest
432 голосов
/ 29 сентября 2008

Есть ли способ определить, сколько ядер у машины есть из C / C ++ независимо от платформы? Если такого не существует, как насчет его определения для каждой платформы (Windows / * nix / Mac)?

Ответы [ 20 ]

663 голосов
/ 30 сентября 2008

C ++ 11

//may return 0 when not able to detect
unsigned concurentThreadsSupported = std::thread::hardware_concurrency();

Ссылка: std :: thread :: hardware_concurrency


В C ++ до C ++ 11 нет переносимого способа. Вместо этого вам необходимо использовать один или несколько из следующих методов (защищенных соответствующими #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];
    
196 голосов
/ 29 сентября 2008

Эта функциональность является частью стандарта C ++ 11.

#include <thread>

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

Для более старых компиляторов вы можете использовать библиотеку Boost.Thread .

#include <boost/thread.hpp>

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

В любом случае hardware_concurrency() возвращает количество потоков, которые аппаратное обеспечение способно выполнять одновременно, на основе количества ядер ЦП и модулей гиперпоточности.

55 голосов
/ 13 октября 2008

OpenMP поддерживается на многих платформах (включая Visual Studio 2005) и предлагает

int omp_get_num_procs();

функция, которая возвращает количество процессоров / ядер, доступных на момент вызова.

37 голосов
/ 30 сентября 2008

Если у вас есть доступ на ассемблере, вы можете использовать инструкцию CPUID для получения всевозможной информации о CPU. Он переносим между операционными системами, хотя вам нужно будет использовать информацию от производителя, чтобы определить, как найти количество ядер. Вот документ, который описывает, как это сделать на чипах Intel , а на странице 11 этот описывает спецификацию AMD.

31 голосов
/ 09 июня 2010

(Почти) Платформа Независимая функция в 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
}
15 голосов
/ 29 сентября 2008

В Linux вы можете прочитать файл / proc / cpuinfo и подсчитать количество ядер.

10 голосов
/ 12 октября 2008

Обратите внимание, что «число ядер» может быть не особенно полезным числом, вам, возможно, придется уточнить его немного больше. Как вы хотите сосчитать многопоточные процессоры, такие как Intel HT, IBM Power5 и Power6, и наиболее известные из них Sun Niagara / UltraSparc T1 и T2? Или, что еще интереснее, MIPS 1004k с двумя уровнями аппаратного потока (супервизор и пользовательский уровень) ... Не говоря уже о том, что происходит, когда вы переходите на системы с поддержкой гипервизора, где на оборудовании могут быть десятки процессоров, но ваша конкретная ОС видит только несколько.

Лучшее, на что вы можете надеяться, это сообщить количество логических процессоров, которые есть в вашем локальном разделе ОС. Забудьте о том, чтобы увидеть настоящую машину, если вы не являетесь гипервизором. Единственное исключение из этого правила сегодня на земле x86, но конец не виртуальных машин скоро наступит ...

7 голосов
/ 13 октября 2008

Еще один рецепт Windows: используйте общесистемную переменную среды NUMBER_OF_PROCESSORS:

printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
7 голосов
/ 29 сентября 2008

Вы, вероятно, не сможете получить его независимо от платформы. Windows вы получаете количество процессоров.

Информация о системе Win32

5 голосов
/ 03 сентября 2012

Больше на OS X: sysconf(_SC_NPROCESSORS_ONLN) доступно только версии> = 10.5, а не 10.4.

Альтернативой является код HW_AVAILCPU/sysctl() BSD, который доступен в версиях> = 10.2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...