Как узнать количество * логических * ядер в 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

Еще проще:

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 'Total Number Of Cores'

Использовать 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, и это все, что делает модификация для вас.)


Любой другой ответ, приведенный здесь, либо

  1. дает неверную информацию
  2. не дает информации, из-за ошибки в реализации команды
  3. работает невероятно медленно (занимает большую часть минуты, чтобы завершить), или
  4. дает слишком много данных, и, следовательно, может быть полезно для интерактивного использования, но бесполезно, если вы хотите использовать данные программно (например, в качестве ввода для такой команды, как 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);
Другие вопросы по тегам