Программно определить количество ядер на компьютере
есть ли способ определить, сколько ядер машина имеет от C / C++ независимым от платформы способом? Если такой вещи не существует, как насчет ее определения для каждой платформы (Windows/ * nix / Mac)?
20 ответов
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];
эта функция является частью стандарта C++11.
#include <thread>
unsigned int nthreads = std::thread::hardware_concurrency();
для старых компиляторов, вы можете использовать импульс.Нить библиотека.
#include <boost/thread.hpp>
unsigned int nthreads = boost::thread::hardware_concurrency();
В любом случае hardware_concurrency()
возвращает количество потоков, которые аппаратное обеспечение способно выполнять одновременно на основе количества ядер процессора и гиперпотоков.
OpenMP поддерживается на многих платформах (включая Visual Studio 2005) и предлагает
int omp_get_num_procs();
функция, которая возвращает количество процессоров/ядер, доступных во время вызова.
Если у вас есть доступ к ассемблеру, вы можете использовать инструкцию CPUID для получения всевозможной информации о процессоре. Он переносится между операционными системами, хотя вам нужно будет использовать информацию производителя, чтобы определить, как найти Количество ядер. Вот!--1-->документ, который описывает, как это сделать на чипы Intel, и страница 11 из этот описывает спецификацию AMD.
(почти) независимая от платформы функция в 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
}
обратите внимание, что" количество ядер " может быть не особенно полезным числом, возможно, вам придется квалифицировать его немного больше. Как вы хотите считать многопоточные процессоры, такие как Intel HT, IBM Power5 и Power6, и, самое известное, Sun Niagara/UltraSparc T1 и T2? Или, что еще более интересно, MIPS 1004k с двумя уровнями аппаратной потоковой передачи (супервизор и пользовательский уровень)... Не говоря уже о том, что происходит при переходе в системы с поддержкой гипервизора, где оборудование может иметь десятки процессоров но ваша ОС видит только несколько.
лучшее, на что вы можете надеяться, это сообщить количество логических процессоров, которые у вас есть в локальном разделе ОС. Забудьте о том, чтобы видеть истинную машину, если вы не гипервизор. Единственное исключение из этого правила сегодня находится в x86 land, но конец не виртуальных машин наступает быстро...
еще один рецепт Windows: используйте общесистемную переменную среды NUMBER_OF_PROCESSORS
:
printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
вы, вероятно, не сможет сделать его независимым от платформы способом. Windows вы получаете количество процессоров.
подробнее о OS X:sysconf(_SC_NPROCESSORS_ONLN)
доступны только версии >= 10.5, а не 10.4.
альтернативой является HW_AVAILCPU/sysctl()
код BSD, который доступен в версиях >= 10.2.
Windows Server 2003 и более поздних версий позволяет использовать функцию GetLogicalProcessorInformation
не связано с C++, но в Linux я обычно делаю:
grep processor /proc/cpuinfo | wc -l
удобно для скриптовых языков, таких как bash/perl/python/ruby.
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.
hwloc (http://www.open-mpi.org/projects/hwloc/) стоит посмотреть. Хотя требуется другая интеграция библиотеки в ваш код, но она может предоставить всю информацию о вашем процессоре (количество ядер, топология и т. д.)
в 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
OS X alternative: решение, описанное ранее на основе [[NSProcessInfo processInfo] processorCount], доступно только в OS X 10.5.0, согласно документам. Для более ранних версий OS X Используйте функцию углерода MPProcessors ().
Если вы программист какао, не пугайтесь того факта, что это углерод. Вам просто нужно добавить углеродную структуру в свой проект Xcode, и MPProcessors () будут доступны.
в linux лучший программный способ, насколько я знаю, использовать
sysconf(_SC_NPROCESSORS_CONF)
или
sysconf(_SC_NPROCESSORS_ONLN)
это не стандарт, но в моей странице для Linux.
Для Win32:
в то время как GetSystemInfo() получает количество логическое процессоры, использовать GetLogicalProcessorInformationEx () чтобы получить номер физическая процессоры.
вы также можете использовать WMI в .net, но затем вы зависите от запущенной службы wmi так далее. Иногда он работает локально, но затем терпит неудачу, когда тот же код запускается на серверах. Я считаю, что это проблема пространства имен, связанная с "именами", значения которых Вы читаете.
в Linux вы можете проверить dmesg и отфильтровать строки, где ACPI инициализирует процессоры, что-то вроде:
dmesg | grep 'ACPI: Processor
'
другая возможность - использовать dmidecode для фильтрации информации о процессоре.