Как узнать количество * логических * ядер в Mac OS X?
Как узнать из командной строки, сколько ядер на машине, когда вы работаете в Mac OS X? В Linux я использую:
x=$(awk '/^processor/ {++n} END {print n+1}' /proc/cpuinfo)
Это не идеально, но это близко. Это предназначено, чтобы накормить make
Вот почему он дает результат на 1 больше, чем фактическое число. И я знаю, что приведенный выше код может быть написан более плотно в Perl или может быть написан с использованием grep, wc и cut, но я решил, что вышеупомянутое было хорошим компромиссом между краткостью и удобочитаемостью.
ОЧЕНЬ ПОЗДНО РЕДАКТИРОВАТЬ: Просто чтобы уточнить: я спрашиваю, сколько доступно логических ядер, потому что это соответствует тому, сколько одновременных заданий я хочу make
порождать Ответ jkp, уточненный Крисом Ллойдом, был именно тем , что мне было нужно. YMMV.
17 ответов
Вы можете сделать это с помощью утилиты sysctl:
sysctl -n hw.ncpu
Это должно быть кроссплатформенным. По крайней мере, для Linux и Mac OS X.
python -c 'import multiprocessing as mp; print(mp.cpu_count())'
Немного медленно, но работает.
getconf
работает как в Mac OS X, так и в Linux, на всякий случай, если вам нужно, чтобы он был совместим с обеими системами:
$ getconf _NPROCESSORS_ONLN
12
system_profiler SPHardwareDataType показывает, что у меня 1 процессор и 4 ядра.
[~] system_profiler SPHardwareDataType Оборудование:
Hardware Overview:
Model Name: MacBook Pro
Model Identifier: MacBookPro9,1
Processor Name: Intel Core i7
Processor Speed: 2.6 GHz
Number of Processors: 1
Total Number of Cores: 4
<snip>
[~]
Однако, sysctl не согласен:
[~] sysctl -n hw.logicalcpu 8 [~] sysctl -n hw.physicalcpu 4 [~]
Но sysctl выглядит правильно, так как когда я запускаю программу, которая должна занимать все слоты процессора, я вижу, что эта программа занимает около 800% времени процессора (вверху):
PID COMMAND% CPU
4306 топ 5.6
4304 Java 745,7
4296 Расположение 0,0
Для этого в C вы можете использовать семейство функций sysctl(3):
int count;
size_t count_len = sizeof(count);
sysctlbyname("hw.logicalcpu", &count, &count_len, NULL, 0);
fprintf(stderr,"you have %i cpu cores", count);
Интересные значения для использования вместо "hw.logicalcpu", который подсчитывает количество ядер:
hw.physicalcpu - The number of physical processors available in the current power management mode.
hw.physicalcpu_max - The maximum number of physical processors that could be available this boot.
hw.logicalcpu - The number of logical processors available in the current power management mode.
hw.logicalcpu_max - The maximum number of logical processors that could be available this boot.
Использовать system_profiler | grep "Cores"
команда.
У меня есть:
MacBook Pro Retina, середина 2012 г.
Процессор: 2,6 ГГц Intel Core i7
user$ system_profiler | grep "Cores"
Total Number of Cores: 4
user$ sysctl -n hw.ncpu
8
Согласно Википедии, ( http://en.wikipedia.org/wiki/Intel_Core) нет Core i7 с 8 физическими ядрами, так что идея Hyperthreading должна быть именно такой. игнорировать sysctl
и использовать system_profiler
значение для точности. Реальный вопрос заключается в том, можете ли вы эффективно запускать приложения с 4 ядрами (длинные задания компиляции?), Не прерывая другие процессы.
Запуск компилятора, параллелизованного с 4 ядрами, не оказывает существенного влияния на обычные операции ОС. Так что, возможно, рассматривать его как 8 ядер не так уж и плохо.
Как сказал в комментарии jkp, это не показывает фактическое количество физических ядер. чтобы получить количество физических ядер, вы можете использовать следующую команду:
system_profiler SPHardwareDataType
Это не было указано в исходном вопросе (хотя я видел сообщение OP в комментариях, что это не вариант), но многие разработчики на macOS установили диспетчер пакетов Homebrew.
Для будущих разработчиков, которые сталкиваются с этим вопросом, пока существует предположение (или требование) об установке Homebrew (например, в инженерной организации в компании): nproc
является одним из распространенных двоичных файлов GNU, который включен в coreutils
пакет.
brew install coreutils
Если у вас есть сценарии, которые вы бы предпочли написать один раз (для Linux + macOS), а не дважды, или чтобы избежать if
блоки, где вам нужно определить ОС, чтобы знать, звонить или нет nproc
против sysctl -n hw.logicalcpu
, это может быть лучшим вариантом.
Следующая команда дает вам всю информацию о вашем процессоре
$ sysctl -a | sort | grep cpu
Это можно сделать более портативным способом:
$ nproc --all
32
Совместим с macOS и Linux.
ПОЯСНЕНИЯ
Когда этот вопрос был задан, ОП не сказал, что ему нужно количество ЛОГИЧЕСКИХ ядер, а не фактическое количество ядер, поэтому этот ответ логически (без каламбура) отвечает способом, позволяющим получить фактическое количество реальных физических ядер, а не число, которое ОС пытается виртуализировать с помощью гиперпоточности вуду.
ОБНОВЛЕНИЕ, ЧТОБЫ ОБРАЩАТЬСЯ В ЛОШАДЬ В YOSEMITE
Из-за странной ошибки в OS X Yosemite (и, возможно, более новых версиях, таких как предстоящая El Capitan), я сделал небольшую модификацию. (Старая версия все еще работала на отлично, если вы просто игнорируете STDERR, и это все, что делает модификация для вас.)
Любой другой ответ, приведенный здесь, либо
- дает неверную информацию
- не дает информации, из-за ошибки в реализации команды
- работает невероятно медленно (занимает большую часть минуты, чтобы завершить), или
- дает слишком много данных, и, следовательно, может быть полезно для интерактивного использования, но бесполезно, если вы хотите использовать данные программно (например, в качестве ввода для такой команды, как
bundle install --jobs 3
где вы хотите номер вместо3
быть на единицу меньше количества ядер, которое у вас есть, или, по крайней мере, не больше количества ядер)
Способ получить только количество ядер, надежно, правильно, достаточно быстро и без дополнительной информации или даже дополнительных символов вокруг ответа, заключается в следующем:
system_profiler SPHardwareDataType 2> /dev/null | grep 'Total Number of Cores' | cut -d: -f2 | tr -d ' '
Комментарии к 2 хорошим ответам выше:
1) повторно принятый ответ (и комментарии) от jkp: hw.ncpu, по-видимому, устарел в пользу hw.logicalcpu ( https://ghc.haskell.org/trac/ghc/ticket/8594)
2) обновление 2014 года от Karl Ehr: на моем компьютере (с процессором Intel Core i7 2,5 ГГц),sysctl -a | grep machdep.cpu | grep per_package
возвращает разные числа:
machdep.cpu.logical_per_package: 16
machdep.cpu.cores_per_package: 8
Желаемые значения:
machdep.cpu.core_count: 4
machdep.cpu.thread_count: 8
Какой матч:
hw.physicalcpu: 4
hw.logicalcpu: 8
На MacBook Pro под управлением Mavericks, sysctl -a | grep hw.cpu
вернет только некоторые загадочные детали. Более подробная и доступная информация раскрывается в machdep.cpu
раздел, то есть:
sysctl -a | grep machdep.cpu
В частности, для процессоров с HyperThreading
(HT), вы увидите общее количество перечисленных процессоров (logical_per_package
) как удвоенный показатель физического ядра (cores_per_package
).
sysctl -a | grep machdep.cpu | grep per_package
Кроссплатформенное решение:
nproc 2>/dev/null || sysctl -n hw.logicalcpu
Чтобы продолжить ответ @alfwatt , я пошел дальше и использовалsysctlnametomib
чтобы получить значения MIB для всех этих записей (macOS 13.6 здесь).
Согласно справочной странице:
тот
sysctl
функция выполняется примерно втрое быстрее, чем тот же запрос, сделанный черезsysctlbyname
функция
Поэтому я думаю, что стоит пойти по этому пути. Вот значения MIB для каждого соответствующего строкового значения:
Вот как вы их используете ( я использую первый в качестве примера):
int mib[2] = {6, 3}; // MIB
u_int mib_size = 2; // it's not actually the size; it's the count
int ret_value = 0; // where the returned value will be stored
size_t ret_size = sizeof(int); // size of the area of the return value
int sc = sysctl(mib, mib_size, &ret_value, &ret_size, NULL, 0);
// if sc != -1, we're good:
printf("the value is: %d\n", ret_value);