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

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

Ответы [ 20 ]

5 голосов
/ 29 мая 2017

Windows (x64 и Win32) и C ++ 11

Количество групп логических процессоров, совместно использующих одно ядро ​​процессора. (с использованием GetLogicalProcessorInformationEx , см. Также GetLogicalProcessorInformation )

size_t NumberOfPhysicalCores() noexcept {

    DWORD length = 0;
    const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length);

    Assert(result_first == FALSE);
    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 == TRUE);

    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"). Вместо этого довольно тонко читать документацию (явно представленную для GetLogicalProcessorInformation и неявно представленную для GetLogicalProcessorInformationEx) в MSDN.

Количество логических процессоров. (Использование 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.

4 голосов
/ 29 сентября 2008

Windows Server 2003 и более поздние версии позволяют использовать функцию GetLogicalProcessorInformation

http://msdn.microsoft.com/en-us/library/ms683194.aspx

4 голосов
/ 21 марта 2011

Не связано с C ++, но в Linux я обычно так и делаю:

grep processor /proc/cpuinfo | wc -l

Удобно для скриптовых языков, таких как bash / perl / python / ruby.

3 голосов
/ 09 июня 2014

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

Тот же подход в оболочке с использованием grep:

grep -c ^processor /proc/cpuinfo

Или

grep -c ^cpu /proc/stat # subtract 1 from the result
3 голосов
/ 19 июля 2011

hwloc (http://www.open -mpi.org / projects / hwloc /) стоит посмотреть. Хотя требуется интеграция другой библиотеки в ваш код, но она может предоставить всю информацию о вашем процессоре (количество ядер, топология и т.

2 голосов
/ 27 июня 2016

Для Win32:

Пока GetSystemInfo () возвращает количество логических процессоров, используйте GetLogicalProcessorInformationEx () чтобы получить количество физических процессоров.

2 голосов
/ 29 сентября 2008

Насколько мне известно, в Linux лучший программный способ - использовать

sysconf(_SC_NPROCESSORS_CONF)

или

sysconf(_SC_NPROCESSORS_ONLN)

Они не являются стандартными, но есть в моей справочной странице по Linux.

2 голосов
/ 13 июля 2009

Альтернатива OS X: решение, описанное ранее на основе [[NSProcessInfo processInfo] processorCount], доступно только в OS X 10.5.0, в соответствии с документацией. Для более ранних версий OS X используйте функцию Carbon MPProcessors ().

Если вы программист Какао, не пугайтесь того факта, что это Carbon. Вам просто нужно добавить платформу Carbon в ваш проект Xcode, и MPProcessors () будет доступен.

0 голосов
/ 21 декабря 2008

вы также можете использовать WMI в .net, но тогда вы зависите от работающей службы wmi и т. д. Иногда это работает локально, но затем происходит сбой, когда тот же код выполняется на серверах. Я считаю, что это проблема пространства имен, связанная с «именами», значения которых вы читаете.

0 голосов
/ 26 марта 2009

В Linux вы можете извлекать dmesg и фильтровать строки, в которых ACPI инициализирует процессоры, что-то вроде:

dmesg | grep 'ACPI: Processor * * 1004

Другая возможность - использовать dmidecode для фильтрации информации о процессоре.

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