Как узнать количество процессоров / ядер в Linux из командной строки?

400

У меня есть этот script, но я не знаю, как получить последний элемент в распечатке:

cat /proc/cpuinfo | awk '/^processor/{print $3}'

Последний элемент должен быть числом процессоров, минус 1.

  • 7
    В любом случае, вам не нужно cat до awk : просто awk '<script>' /proc/cpuinfo , вот так: awk '/^processor/{n+=1}END{print n}' /proc/cpuinfo . И вы получаете без "минус один".
Теги:
cpu

22 ответа

433
Лучший ответ
cat /proc/cpuinfo | awk '/^processor/{print $3}' | wc -l

или просто

grep -c ^processor /proc/cpuinfo     

которая будет подсчитывать количество строк, начинающихся с "процессор" в /proc/cpuinfo

Для систем с гиперпоточностью вы можете использовать

grep ^cpu\\scores /proc/cpuinfo | uniq |  awk '{print $4}' 

который должен вернуть (например) 8 (тогда как команда выше вернет 16)

  • 37
    Обратите внимание, что оба из них в конечном итоге будут считать вдвое больше ядер, чем реально существует, если вы работаете в системе с гиперпоточностью (например, P4 или Core i7).
  • 2
    ответ дополнен опцией гиперпоточности
Показать ещё 10 комментариев
490

Обработка содержимого /proc/cpuinfo излишне барокко. Используйте nproc, который является частью coreutils, поэтому он должен быть доступен для большинства Linux-установок.

Команда nproc печатает количество доступных для текущего процесса процессоров, что может быть меньше количества онлайн-процессоров.

Чтобы найти число всех установленных ядер/процессоров, используйте nproc --all

На моей 8-ядерной машине:

$ nproc --all
8
  • 5
    различает ли виртуальное ядро от физического?
  • 0
    Не то чтобы я вижу. nproc сообщает «2» на моей виртуальной машине с двумя виртуальными ядрами и «8» на моей реальной машине с 8.
Показать ещё 7 комментариев
193

Наиболее портативным решением, которое я нашел, является команда getconf:

getconf _NPROCESSORS_ONLN

Это работает как на Linux, так и на Mac OS X. Еще одно преимущество этого в некоторых других подходах заключается в том, что getconf существует уже давно. Некоторые из старых Linux-машин, на которых я должен работать, не имеют доступных команд nproc или lscpu, но они имеют getconf.

Замечание редактора: Пока утилита getconf соответствует требованиям POSIX, конкретные значения _NPROCESSORS_ONLN и _NPROCESSORS_CONF не. Тем не менее, как заявлено, они работают на платформах Linux, а также на macOS; на FreeBSD/PC-BSD вы должны опустить ведущий _.

  • 9
    Это сработало для меня в Red Hat Entreprise Linux 5.4, Centos 6.5 & 7 и Mac OSX 10.9 (Mavericks). Похоже, это наиболее переносимый файл, так как lscpu не устанавливается по умолчанию в этих системах. Спасибо!
  • 1
    Согласен. Это довольно портативный.
Показать ещё 10 комментариев
67

Предисловие:

  • Проблема с ответами /proc/cpuinfo -based заключается в том, что они анализируют информацию, предназначенную для потребления человеком, и поэтому не имеют стабильного формата, предназначенного для анализа машины: формат вывода может различаться для разных платформ и условий выполнения; использование lscpu -p в Linux (и sysctl в macOS) позволяет обойти эту проблему.

  • getconf _NPROCESSORS_ONLN/getconf NPROCESSORS_ONLN не различает логические и физические процессоры.


Здесь приведен фрагмент кода sh (POSIX-совместимый), который работает в Linux и macOS для определения количества оперативных логических или физических процессоров; смотрите комментарии для деталей.

Использует lscpu для Linux и sysctl для macOS.

Замечание по терминологии: ЦП относится к наименьшей единице обработки, видимой ОС. Ядра без гиперпоточности соответствуют одному ЦП, в то время как ядра с многопоточностью содержат более 1 (обычно: 2) - логического - ЦП.
Linux использует следующую таксономию, начиная с наименьшего блока: CPU <core <socket <book <, где каждый уровень содержит 1 или более экземпляров следующего более низкого уровня.
Мои знания здесь немного шатки - дайте мне знать, если я ошибаюсь. Кто-нибудь знает, что такое "книга" в этом контексте?

#!/bin/sh

# macOS:           Use 'sysctl -n hw.*cpu_max', which returns the values of 
#                  interest directly.
#                  CAVEAT: Using the "_max" key suffixes means that the *maximum*
#                          available number of CPUs is reported, whereas the
#                          current power-management mode could make *fewer* CPUs 
#                          available; dropping the "_max" suffix would report the
#                          number of *currently* available ones; see [1] below.
#
# Linux:           Parse output from 'lscpu -p', where each output line represents
#                  a distinct (logical) CPU.
#                  Note: Newer versions of 'lscpu' support more flexible output
#                        formats, but we stick with the parseable legacy format 
#                        generated by '-p' to support older distros, too.
#                        '-p' reports *online* CPUs only - i.e., on hot-pluggable 
#                        systems, currently disabled (offline) CPUs are NOT
#                        reported.

# Number of LOGICAL CPUs (includes those reported by hyper-threading cores)
  # Linux: Simply count the number of (non-comment) output lines from 'lscpu -p', 
  # which tells us the number of *logical* CPUs.
logicalCpuCount=$([ $(uname) = 'Darwin' ] && 
                       sysctl -n hw.logicalcpu_max || 
                       lscpu -p | egrep -v '^#' | wc -l)

# Number of PHYSICAL CPUs (cores).
  # Linux: The 2nd column contains the core ID, with each core ID having 1 or
  #        - in the case of hyperthreading - more logical CPUs.
  #        Counting the *unique* cores across lines tells us the
  #        number of *physical* CPUs (cores).
physicalCpuCount=$([ $(uname) = 'Darwin' ] && 
                       sysctl -n hw.physicalcpu_max ||
                       lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l)

# Print the values.
cat <<EOF
# of logical CPUs:  $logicalCpuCount
# of physical CPUS: $physicalCpuCount
EOF

[1] документация по macOS sysctl (3)

Обратите внимание, что производные от BSD системы, отличные от macOS - например, FreeBSD - поддерживают hw.ncpu ключ hw.ncpu для sysctl, который устарел в macOS; Мне неясно, какой из новых ключей hw.npu соответствует: hw.(logical|physical)cpu_[max].

Совет от @teambob за помощь в исправлении команды lscpu Physical-CPU-count.

Оговорка: lscpu -p Выход не включает столбец "книгу" (man страница упоминает "книгу" как единое целое между розеткой и узлом в таксономической иерархии). Если "книги" находятся в игре в данной системе Linux (кто-нибудь знает, когда и как?), Команда физического подсчета ЦП может lscpu отчет (это основано на предположении, что lscpu сообщает идентификаторы, которые не являются уникальными по всему объекты более высокого уровня, например: 2 разных ядра из 2 разных сокетов могут иметь одинаковый идентификатор).


Если вы сохраните приведенный выше код как, скажем, cpus сценария оболочки, сделаете его исполняемым с помощью chmod +x cpus и поместите его в папку в вашем $PATH, вы увидите вывод, подобный следующему:

$ cpus
logical  4
physical 4
  • 1
    Да, извините, вы правы насчет команды сортировки. Я не могу найти никакой информации о книгах, кроме руководства lscpu. Я думаю, что это связано с NUMA en.wikipedia.org/wiki/Non-uniform_memory_access
  • 1
    Я думаю, что большинство решений здесь игнорируют машины с несколькими сокетами, в отличие от этого. Спасибо!
12

lscpu собирает информационную форму архитектуры процессора /proc/cpuinfon в удобном для чтения формате:

# lscpu


Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    1
Core(s) per socket:    4
CPU socket(s):         2
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 15
Stepping:              7
CPU MHz:               1866.669
BogoMIPS:              3732.83
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
NUMA node0 CPU(s):     0-7
11

Это сработало для меня. tail -nX позволяет вам захватывать только последние строки X.

cat /proc/cpuinfo | awk '/^processor/{print $3}' | tail -1

Если у вас гиперпоточность, это должно работать для захвата количества ядер физического.

grep "^core id" /proc/cpuinfo | sort -u | wc -l
  • 3
    сортировать | uniq == сортировать -u
  • 0
    здорово, я этого не знал :)
Показать ещё 4 комментария
9

Для общего количества физических ядер:

grep '^core id' /proc/cpuinfo |sort -u|wc -l

В многопроцессорных машинах (или всегда) умножьте полученный результат на число сокетов:

echo $(($(grep "^physical id" /proc/cpuinfo | awk '{print $4}' | sort -un | tail -1)+1))

@mklement0 имеет довольно приятный ответ ниже, используя lscpu. Я написал более сжатую версию в комментариях

7

Кроссплатформенное решение для Linux, MacOS, Windows:

CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu || echo "$NUMBER_OF_PROCESSORS")
7

Использование getconf действительно является самым переносимым способом, однако переменная имеет разные имена в BSD и Linux для getconf, поэтому вам нужно протестировать оба, поскольку этот принцип подсказывает: https://gist.github.com/jj1bdx/5746298 (также включает исправление Solaris с использованием ksh)

Я лично использую:

$ getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null || echo 1

И если вы хотите это на python, вы можете просто использовать использование syscall getconf, импортировав модуль os:

$ python -c 'import os; print os.sysconf(os.sysconf_names["SC_NPROCESSORS_ONLN"]);'

Что касается nproc, он является частью GNU Coreutils, поэтому по умолчанию он недоступен в BSD. Он использует sysconf() также после некоторых других методов.

6

Вы также можете использовать Python! Чтобы получить количество физических ядер:

$ python -c "import psutil; print(psutil.cpu_count(logical=False))"
4

Чтобы получить количество гиперзаходных ядер:

$ python -c "import psutil; print(psutil.cpu_count(logical=True))"
8
  • 0
    В python 2.7.15 эти команды ничего не печатают. В REPL они делают.
  • 1
    @VytenisBivainis Спасибо, я исправил свой ответ!
6

Если вы хотите сделать это, чтобы он работал на Linux и OS X, вы можете сделать:

CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
  • 0
    Это также работает для FreeBSD и, возможно, для других.
  • 0
    Мой OSX 10.10.3 говорит, что sysctl: command not found
3

Следующее должно предоставить вам количество "реальных" ядер как для гиперпотоковой, так и для не гиперпотоковой системы. По крайней мере, он работал во всех моих тестах.

awk -F: '/^physical/ && !ID[$2] { P++; ID[$2]=1 }; /^cpu cores/ { CORES=$2 };  END { print CORES*P }' /proc/cpuinfo
  • 0
    -1, это возвращает 0 для одного ядра с Opteron 4170 HE, но возвращает 4 для восьмиядерного блока с Opteron 3280. ... часть меня действительно желает, чтобы этот однолинейный работал!
2

Здесь я использую для подсчета количества физических ядер, находящихся в сети в Linux:

lscpu --online --parse=Core,Socket | grep --invert-match '^#' | sort --unique | wc --lines

или вкратце:

lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
2

Вы можете использовать один из следующих методов для определения количества ядер физических.

  • Подсчитайте количество уникальных идентификаторов ядра (примерно эквивалентно grep -P '^core id\t' /proc/cpuinfo | sort -u | wc -l).

    awk '/^core id\t/ {cores[$NF]++} END {print length(cores)}' /proc/cpuinfo

  • Умножьте количество "ядер на сокет" на количество сокетов.

    lscpu | awk '/^Core\(s\) per socket:/ {cores=$NF}; /^Socket\(s\):/ {sockets=$NF}; END{print cores*sockets}'

  • Подсчитайте количество уникальных логических процессоров, используемых ядром Linux. Опция -p генерирует вывод для легкого разбора и совместим с более ранними версиями lscpu.

    lscpu -p | awk -F, '$0 !~ /^#/ {cores[$1]++} END {print length(cores)}'


Чтобы повторить то, что говорили другие, существует ряд связанных свойств.

Чтобы определить количество доступных процессоров:

getconf _NPROCESSORS_ONLN
grep -cP '^processor\t' /proc/cpuinfo

Определить количество доступных единиц обработки (не обязательно такое же количество ядер). Это гиперпоточность.

nproc

Я не хочу заходить слишком далеко вниз по кроличьей дыре, но вы также можете определить количество сконфигурированных процессоров (в отличие от просто доступных/онлайн-процессоров) через getconf _NPROCESSORS_CONF. Чтобы определить общее количество CPU (офлайн и онлайн), вы хотите проанализировать вывод lscpu -ap.

  • 0
    это правильный ответ, если вы хотите физические ядра.
1

Эта команда:

echo $(nproc)

Должен вернуть количество или количество ядер, доступных для системы

1

Если все в порядке, что вы можете использовать Python, то модуль numexpr имеет функцию для этого:

In [5]: import numexpr as ne

In [6]: ne.detect_number_of_cores()
Out[6]: 8

также это:

In [7]: ne.ncores
Out[7]: 8

Для запроса этой информации из командной строки используйте:

# runs whatever valid Python code given as a string with '-c' option
$ python -c "import numexpr as ne; print(ne.ncores)"
8

Или просто можно получить эту информацию из функции multiprocessing.cpu_count()

$ python -c "import multiprocessing; print(multiprocessing.cpu_count())"

Или еще проще использовать os.cpu_count()

$ python -c "import os; print(os.cpu_count())"
  • 1
    Есть ли способ заставить это работать как команда в python? Например, я пробовал python -m Numberxpr.ncores, но это не работает.
  • 1
    @MonsieurBeilto Пожалуйста, посмотрите на обновленный ответ!
Показать ещё 1 комментарий
1

Быстрее, без вилки

Эта работа с almsost all .

ncore=0
while read line ;do
    [ "$line" ] && [ -z "${line%processor*}" ] && ncore=$((ncore+1))
  done </proc/cpuinfo
echo $ncore
4

Чтобы оставаться совместимым с , и другие, я использовал ncore=$((ncore+1)) вместо ((ncore++)).

версия

ncore=0
while read -a line ;do
    [ "$line" = "processor" ] && ((ncore++))
  done </proc/cpuinfo
echo $ncore
4
1
cat /proc/cpuinfo | grep processor

Все прошло отлично. Когда я попробовал первый ответ, я получил 3 процессора в качестве выхода. Я знаю, что у меня есть 4 процессора в системе, поэтому я просто сделал grep для процессора, и результат выглядел так:

[root@theservername ~]# cat /proc/cpuinfo | grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3
1

Подсчитайте "базовый идентификатор" на "физический идентификатор" с использованием awk с отклонением на "процессор", если "core id" недоступен (например, малина)

echo $(awk '{ if ($0~/^physical id/) { p=$NF }; if ($0~/^core id/) { cores[p$NF]=p$NF }; if ($0~/processor/) { cpu++ } } END { for (key in cores) { n++ } } END { if (n) {print n} else {print cpu} }' /proc/cpuinfo)
0

Python 3 также предоставляет несколько простых способов получить его:

$ python3 -c "import os; print(os.cpu_count());"

4

$ python3 -c "import multiprocessing; print(multiprocessing.cpu_count())"

4

  • 0
    Это действительно возвращает 8 для меня, когда у меня есть 4 ядра с 2 потоками на каждом ...
0
 dmidecode  | grep -i cpu | grep Version

дает мне

Версия: Intel (R) Xeon (R) CPU E5-2667 v4 @3.20GHz

Версия: Intel (R) Xeon (R) CPU E5-2667 v4 @3.20GHz

Какой правильный подсчет сокета - поиск E5-2667 говорит мне, что у каждого сокета есть 8 cores, поэтому умножьте его на 16 cores на 2 sockets.

Где lscpu дайте мне 20 CPUs - это абсолютно неверно - не знаете почему. (то же самое для cat /proc/cpu - заканчивается 20.

0

Не моя веб-страница, но эта команда из http://www.ixbrian.com/blog/?p=64&cm_mc_uid=89402252817914508279022&cm_mc_sid_50200000=1450827902 отлично работает для меня на centos. Он покажет фактический cpus, даже если включена гиперпоточность.

cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed s/physical/\\nphysical/g | grep -v ^$ | sort | uniq | wc -l

Ещё вопросы

Сообщество Overcoder
Наверх
Меню