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 для получения всевозможной информации о процессоре. Он переносится между операционными системами, хотя вам нужно будет использовать информацию о производителе, чтобы определить, как найти Количество ядер. Вот это документ, который описывает, как это сделать на чипы 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'S 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 альтернатива: решение, описанное ранее на основе [[NSProcessInfo processInfo] processorCount] доступно только в OS X 10.5.0, согласно документам. Для более ранних версий OS X Используйте функцию углерода MPProcessors ().
Если вы программист какао, не пугайтесь того факта, что это углерод. Вам просто нужно добавить Carbon framework в свой проект 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 для фильтрации информации о процессоре.
Comments