Есть ли способ определить, сколько ядер на машине C/С++ не зависит от платформы? Если такой вещи не существует, как определить ее на платформе (Windows/* nix/Mac)?
Программно найти количество ядер на машине
Ответ 1
С++ 11
//may return 0 when not able to detect
unsigned concurentThreadsSupported = std::thread::hardware_concurrency();
Ссылка: std:: thread:: hardware_concurrency
В С++ до С++ 11 нет портативного способа. Вместо этого вам нужно будет использовать один или несколько из следующих методов (защищенных соответствующими строками #ifdef
):
-
Win32
SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); int numCPU = sysinfo.dwNumberOfProcessors;
-
Linux, Solaris, AIX и Mac OS X >= 10.4 (т.е. тигр)
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];
Ответ 2
Эта функциональность является частью стандарта С++ 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()
возвращает количество потоков, которые аппаратное обеспечение может выполнять одновременно на основе количества ядер ЦП и блоков с гиперпотоком.
Ответ 3
OpenMP поддерживается на многих платформах (включая Visual Studio 2005) и предлагает
int omp_get_num_procs();
которая возвращает количество процессоров/ядер, доступных во время вызова.
Ответ 4
Если у вас есть доступ на ассемблере, вы можете использовать инструкцию CPUID для получения всякой информации о процессоре. Он переносится между операционными системами, хотя вам нужно будет использовать информацию, специфичную для производителя, чтобы определить, как найти количество ядер. Здесь документ, описывающий, как это сделать на чипах Intel, и страница этот описывает спецификацию AMD.
Ответ 5
(Почти) Независимая от платформы функция в 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
}
Ответ 6
В Linux вы можете прочитать файл /proc/cpuinfo и подсчитать ядра.
Ответ 7
Обратите внимание, что "количество ядер" может не оказаться особенно полезным числом, вам, возможно, придется немного подбирать его. Как вы можете рассчитывать многопоточные процессоры, такие как Intel HT, IBM Power5 и Power6, и, самое главное, Sun Niagara/UltraSparc T1 и T2? Или еще более интересно, MIPS 1004k с двумя уровнями аппаратной потоковой передачи (супервизор и пользовательский уровень)... Не говоря уже о том, что происходит, когда вы переходите в поддерживаемые гипервизорами системы, где аппаратное обеспечение может иметь десятки процессоров, но ваша конкретная ОС видит только несколько.
Лучшее, на что вы можете надеяться, это указать количество блоков логической обработки, которые у вас есть в вашем локальном разделе ОС. Не забудьте увидеть истинную машину, если вы не гипервизор. Единственное исключение из этого правила сегодня - на земле x86, но конец не виртуальных машин идет быстро...
Ответ 8
Вероятно, вы не сможете получить его независимым от платформы способом. Windows вы получаете количество процессоров.
Ответ 9
Еще один рецепт Windows: используйте общесистемную переменную окружения NUMBER_OF_PROCESSORS
:
printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
Ответ 10
Windows (x64 и Win32) и С++ 11
Число групп логических процессоров, совместно использующих одно ядро процессора. (также используя GetLogicalProcessorInformationEx, см. также GetLogicalProcessorInformation)
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;
}
Обратите внимание, что реализация 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/С++ 98/С++ 03.
Ответ 11
Подробнее о OS X: sysconf(_SC_NPROCESSORS_ONLN)
доступны только версии >= 10.5, а не 10.4.
Альтернативой является код HW_AVAILCPU/sysctl()
BSD, который доступен в версиях >= 10.2.
Ответ 12
Windows Server 2003 и более поздние версии позволяют использовать функцию GetLogicalProcessorInformation
Ответ 13
Не связан с С++, но в Linux я обычно делаю:
grep processor /proc/cpuinfo | wc -l
Удобен для языков сценариев, таких как bash/perl/python/ruby.
Ответ 14
hwloc (http://www.open-mpi.org/projects/hwloc/) стоит посмотреть. Хотя для интеграции вашего кода требуется другая интеграция библиотеки, но он может предоставить всю информацию о вашем процессоре (количество ядер, топология и т.д.).
Ответ 15
В 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
Ответ 16
В linux лучший программный способ, насколько я знаю, заключается в использовании
sysconf(_SC_NPROCESSORS_CONF)
или
sysconf(_SC_NPROCESSORS_ONLN)
Они не являются стандартными, но находятся на моей странице man для Linux.
Ответ 17
Альтернатива OS X: решение, описанное ранее на основе [[NSProcessInfo processInfo] processorCount], доступно только в OS X 10.5.0, согласно документам. Для более ранних версий OS X используйте функцию Carbon MPProcessors().
Если вы программист Cocoa, не волнуйтесь из-за того, что это Carbon. Вам просто нужно добавить каркас Carbon к вашему проекту Xcode, и MPProcessors() будет доступен.
Ответ 18
Для Win32:
В то время как GetSystemInfo() получает вам количество логических процессоров, используйте GetLogicalProcessorInformationEx()для получения количества физических процессоров.
Ответ 19
вы также можете использовать WMI в .net, но тогда вы зависите от службы wmi и т.д. Иногда он работает локально, но затем не работает, когда один и тот же код запускается на серверах. Я считаю, что проблема пространства имен связана с "именами", значения которых вы читаете.
Ответ 20
В Linux вы можете проверить dmesg и отфильтровать строки, где ACPI инициализирует процессоры, например:
dmesg | grep 'ACPI: Processor
Другая возможность - использовать dmidecode для фильтрации информации о процессоре.