Программно определить количество ядер на машине
Существует ли способ определить количество ядер у машины с помощью C/C++ в независимом от платформы формате? Если такого способа не существует, можно ли узнать это отдельно для каждой платформы (Windows/*nix/Mac)?
5 ответ(ов)
Чтобы написать (почти) независимую от платформы функцию в C, вы можете использовать препроцессорные директивы для проверки операционной системы и получения количества процессоров. Вот пример кода, который реализует данную функцию:
#ifdef _WIN32
#include <windows.h>
#elif defined(__APPLE__) && defined(__MACH__)
#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 defined(__APPLE__) && defined(__MACH__)
int nm[2];
size_t len = sizeof(uint32_t);
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
}
В этом коде используется препроцессор для определения операционной системы. Для Windows вызывается функция GetSystemInfo
, а для macOS используются системные вызовы sysctl
. Для других Unix-подобных систем (например, Linux) используется sysconf
.
Обратите внимание на правильное определение платформы через директиву #elif
, чтобы избежать ошибок компиляции. Эта функция вернет количество доступных процессорных ядер для соответствующей операционной системы.
На Linux вы можете прочитать файл /proc/cpuinfo
и подсчитать количество ядер. Для этого можно использовать команду в терминале:
grep -c ^processor /proc/cpuinfo
Эта команда использует grep
, чтобы найти строки, начинающиеся с "processor", которые соответствуют ядрам вашего процессора, и с помощью опции -c
подсчитывает их количество. Таким образом, вы получите общее число ядер вашего процессора.
Обратите внимание, что "количество ядер" может быть не самым полезным показателем, и вам, возможно, потребуется уточнить его. Как вы хотите учитывать многоядерные процессоры, такие как Intel HT, IBM Power5 и Power6, а также наиболее известные процессоры Sun Niagara/UltraSparc T1 и T2? Или еще интереснее, MIPS 1004k с его двумя уровнями аппаратного потокового выполнения (как для системных, так и для пользовательских потоков)... Не говоря уже о том, что происходит, когда вы переходите на системы с поддержкой гипервизора, где на аппаратном уровне может быть десятки процессоров, но ваша ОС видит только несколько из них.
Лучшее, что вы можете сделать, это сообщить количество логических единиц обработки, доступных в вашей локальной ОС. Забывайте о возможности увидеть настоящую машину, если вы не являетесь гипервизором. Единственным исключением для этого правила на сегодняшний день является мир x86, но конец не-виртуальных машин стремительно приближается...
Вы можете использовать системную переменную окружения NUMBER_OF_PROCESSORS
, чтобы получить количество доступных процессоров в Windows. Вот пример кода на C, который показывает, как это сделать:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
return 0;
}
В этом коде мы вызываем функцию getenv
, чтобы получить значение переменной окружения NUMBER_OF_PROCESSORS
, а затем преобразуем его в целое число с помощью atoi
. Это может быть полезно для динамической настройки задач, основанных на количестве доступных процессоров в системе. Не забудьте, что эта переменная доступна в большинстве версий Windows.
В macOS (OS X) функция sysconf(_SC_NPROCESSORS_ONLN)
доступна только в версиях, начиная с 10.5. Если вы работаете с более ранней версией, такой как 10.4, рекомендуется использовать альтернативный метод с использованием sysctl()
для получения информации о количестве доступных процессоров. В этом случае вам подойдет HW_AVAILCPU
, который доступен, начиная с версии 10.2.
Пример использования sysctl()
для получения количества доступных процессоров:
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
int main() {
int count;
size_t size = sizeof(count);
if (sysctlbyname("hw.availcpu", &count, &size, NULL, 0) != 0) {
perror("sysctl");
return 1;
}
printf("Available CPUs: %d\n", count);
return 0;
}
Таким образом, если вам нужно разработать кросс-версионный код, учитывайте эту информацию о поддерживаемых функциях и используйте sysctl()
в более старых версиях macOS.
Как изменить цвет вывода echo в Linux
Разница между const int*, const int * const и int * const?
Почему переменные нельзя объявлять в операторе switch?
Как вывести список символов из .so файла?
`unsigned int` против `size_t`: когда и что использовать?