[linux] How to obtain the number of CPUs/cores in Linux from the command line?

I have this script, but I do not know how to get the last element in the printout:

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

The last element should be the number of CPUs, minus 1.

This question is related to linux bash cpu

The answer is


Count "core id" per "physical id" method using awk with fall-back on "processor" count if "core id" are not available (like raspberry)

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)

You can use one of the following methods to determine the number of physical CPU cores.

  • Count the number of unique core ids (roughly equivalent to grep -P '^core id\t' /proc/cpuinfo | sort -u | wc -l).

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

  • Multiply the number of 'cores per socket' by the number of sockets.

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

  • Count the number of unique logical CPU's as used by the Linux kernel. The -p option generates output for easy parsing and is compatible with earlier versions of lscpu.

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


Just to reiterate what others have said, there are a number of related properties.

To determine the number of processors available:

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

To determine the number of processing units available (not necessarily the same as the number of cores). This is hyperthreading-aware.

nproc

I don't want to go too far down the rabbit-hole, but you can also determine the number of configured processors (as opposed to simply available/online processors) via getconf _NPROCESSORS_CONF. To determine total number of CPU's (offline and online) you'd want to parse the output of lscpu -ap.


lscpu gathers CPU architecture information form /proc/cpuinfon in human-read-able format:

# 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

See also https://unix.stackexchange.com/questions/468766/understanding-output-of-lscpu.


Quicker, without fork

This work with almsost all .

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

In order to stay compatible with , , and others, I've used ncore=$((ncore+1)) instead of ((ncore++)).

version

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

The most portable solution I have found is the getconf command:

getconf _NPROCESSORS_ONLN

This works on both Linux and Mac OS X. Another benefit of this over some of the other approaches is that getconf has been around for a long time. Some of the older Linux machines I have to do development on don't have the nproc or lscpu commands available, but they have getconf.

Editor's note: While the getconf utility is POSIX-mandated, the specific _NPROCESSORS_ONLN and _NPROCESSORS_CONF values are not. That said, as stated, they work on Linux platforms as well as on macOS; on FreeBSD/PC-BSD, you must omit the leading _.


The above answers are applicable to most situations, but if you are in a docker container environment and your container is limited by CpusetCpus, then you can't actually get the real cpu cores through the above method.

In this case, you need do this to get the real cpu cores:

cat /proc/stat | grep cpu | grep -E 'cpu[0-9]+' | wc -l

Preface:

  • The problem with the /proc/cpuinfo-based answers is that they parse information that was meant for human consumption and thus lacks a stable format designed for machine parsing: the output format can differ across platforms and runtime conditions; using lscpu -p on Linux (and sysctl on macOS) bypasses that problem.

  • getconf _NPROCESSORS_ONLN / getconf NPROCESSORS_ONLN doesn't distinguish between logical and physical CPUs.


Here's a sh (POSIX-compliant) snippet that works on Linux and macOS for determining the number of - online - logical or physical CPUs; see the comments for details.

Uses lscpu for Linux, and sysctl for macOS.

Terminology note: CPU refers to the smallest processing unit as seen by the OS. Non-hyper-threading cores each correspond to 1 CPU, whereas hyper-threading cores contain more than 1 (typically: 2) - logical - CPU.
Linux uses the following taxonomy[1], starting with the smallest unit:
CPU < core < socket < book < node
with each level comprising 1 or more instances of the next lower level.

#!/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) documentation

Note that BSD-derived systems other than macOS - e.g., FreeBSD - only support the hw.ncpu key for sysctl, which are deprecated on macOS; I'm unclear on which of the new keys hw.npu corresponds to: hw.(logical|physical)cpu_[max].

Tip of the hat to @teambob for helping to correct the physical-CPU-count lscpu command.

Caveat: lscpu -p output does NOT include a "book" column (the man page mentions "books" as an entity between socket and node in the taxonomic hierarchy). If "books" are in play on a given Linux system (does anybody know when and how?), the physical-CPU-count command may under-report (this is based on the assumption that lscpu reports IDs that are non-unique across higher-level entities; e.g.: 2 different cores from 2 different sockets could have the same ID).


If you save the code above as, say, shell script cpus, make it executable with chmod +x cpus and place it in folder in your $PATH, you'll see output such as the following:

$ cpus
logical  4
physical 4

[1] Xaekai sheds light on what a book is: "a book is a module that houses a circuit board with CPU sockets, RAM sockets, IO connections along the edge, and a hook for cooling system integration. They are used in IBM mainframes. Further info: http://ewh.ieee.org/soc/cpmt/presentations/cpmt0810a.pdf"


If you just want to count physical cores, this command did it for me.

lscpu -e | tail -n +2 | tr -s " " | cut -d " " -f 4 | sort | uniq | wc -w

Pretty basic, but seems to count actual physical cores, ignoring the logical count


Here's the way I use for counting the number of physical cores that are online on Linux:

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

or in short:

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

Example (1 socket):

> lscpu
...
CPU(s):                28
Thread(s) per core:    2
Core(s) per socket:    14
Socket(s):             1
....
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
14

Example (2 sockets):

> lscpu
...
CPU(s):                56
Thread(s) per core:    2
Core(s) per socket:    14
Socket(s):             2
...
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
28

Example (4 sockets):

> lscpu
...
CPU(s):                64
Thread(s) per core:    2
Core(s) per socket:    8
Socket(s):             4
...
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
32

It is very simple. Just use this command:

lscpu

The following should give you the number of "real" cores on both a hyperthreaded and non-hyperthreaded system. At least it worked in all my tests.

awk -F: '/^physical/ && !ID[$2] { P++; ID[$2]=1 }; /^cpu cores/ { CORES=$2 };  END { print CORES*P }' /proc/cpuinfo

If you want to do this so it works on linux and OS X, you can do:

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

Using getconf is indeed the most portable way, however the variable has different names in BSD and Linux to getconf, so you have to test both, as this gist suggests: https://gist.github.com/jj1bdx/5746298 (also includes a Solaris fix using ksh)

I personally use:

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

And if you want this in python you can just use the syscall getconf uses by importing the os module:

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

As for nproc, it's part of GNU Coreutils, so not available in BSD by default. It uses sysconf() as well after some other methods.


Fravadona's answer is awesome and correct, but it requires the presence of lscpu. Since it is not present on the system where I need the number of physical cores, I tried to come up with one that relies only on proc/cpuinfo

cat /proc/cpuinfo | grep -B2 'core id' | sed 's/siblings.*/'/ | tr -d '[:space:]' | sed 's/--/\n/'g | sort -u | wc -l

It works perfectly, but unfortunately it isn't as robust as Fravadona's, since it will break if

  • the name or order of the fields inside /proc/cpuinfo changes
  • grep replaces the line separator it inserts (currently --) by some other string.

BUT, other than that, it works flawlessly :)

Here is a quick explanation of everything that is happening

grep -B2 'core id'

get only the lines we are interested (i.e "core id" and the 2 preceding lines)

sed 's/siblings.*/'/

remove the "siblings..." line

tr -d '[:space:]'

replace spacing chars

sed 's/--/\n/'g

replace the '--' char, which was inserted by grep, by a line break

sort -u

group by "physical id,core id"

wc -l

count the number of lines

Being a total noobie, I was very pleased with myself when this worked. I never thought I would be able to join the required lines together to group by "physical id" and "core id". It is kind of hacky, but works.

If any guru knows a way to simplify this mess, please let me know.


I also thought cat /proc/cpuinfo would give me the correct answer, however I recently saw that my ARM quad core Cortex A53 system only showed a single core. It seems that /proc/cpuinfo only shows the active cores, whereas:

cat /sys/devices/system/cpu/present

is a better measure of what's there. You can also

cat /sys/devices/system/cpu/online

to see which cores are online, and

cat /sys/devices/system/cpu/offline

to see which cores are offline. The online, offline, and present sysfs entries return the index of the CPUS, so a return value of 0 just means core 0, whereas a return value of 1-3 means cores 1,2, and 3.

See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu


If it's okay that you can use Python, then numexpr module has a function for this:

In [5]: import numexpr as ne

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

also this:

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

To query this information from the command prompt use:

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

Or simply it is possible to get this info from multiprocessing.cpu_count() function

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

Or even more simply use os.cpu_count()

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

Not my web page, but this command from http://www.ixbrian.com/blog/?p=64&cm_mc_uid=89402252817914508279022&cm_mc_sid_50200000=1450827902 works nicely for me on centos. It will show actual cpus even when hyperthreading is enabled.

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


Crossplatform solution for Linux, MacOS, Windows:

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

cat /proc/cpuinfo | grep processor

This worked fine. When I tried the first answer I got 3 CPU's as the output. I know that I have 4 CPUs on the system so I just did a grep for processor and the output looked like this:

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

This worked for me. tail -nX allows you to grab only the last X lines.

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

If you have hyperthreading, this should work for grabbing the number of physical cores.

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

Processing the contents of /proc/cpuinfo is needlessly baroque. Use nproc which is part of coreutils, so it should be available on most Linux installs.

Command nproc prints the number of processing units available to the current process, which may be less than the number of online processors.

To find the number of all installed cores/processors use nproc --all

On my 8-core machine:

$ nproc --all
8

You can also use Python! To get the number of physical cores:

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

To get the number of hyperthreaded cores:

$ python -c "import psutil; print(psutil.cpu_count(logical=True))"
8

For the total number of physical cores:

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

On multiple-socket machines (or always), multiply the above result by the number of sockets:

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

@mklement0 has quite a nice answer below using lscpu. I have written a more succinct version in the comments


Python 3 also provide a few simple ways to get it:

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

4

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

4


Summary: to get physical CPUs do this:

grep 'core id' /proc/cpuinfo | sort -u

to get physical and logical CPUs do this:

grep -c ^processor /proc/cpuinfo

/proc << this is the golden source of any info you need about processes and

/proc/cpuinfo << is the golden source of any CPU information.


 dmidecode  | grep -i cpu | grep Version

gives me

Version: Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz

Version: Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz

Which is correct socket count - looking up the E5-2667 tells me each socket has 8 cores, so multiply and end up with 16 cores across 2 sockets.

Where lscpu give me 20 CPUs - which is totally incorrect - not sure why. (same goes for cat /proc/cpu - ends up with 20.


Use below query to get core details

[oracle@orahost](TESTDB)$ grep -c ^processor /proc/cpuinfo
8

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to cpu

Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2 Difference between core and processor How to enable support of CPU virtualization on Macbook Pro? How to get overall CPU usage (e.g. 57%) on Linux How to obtain the number of CPUs/cores in Linux from the command line? How to create a CPU spike with a bash command How to fast get Hardware-ID in C#? Optimal number of threads per core Linux Process States How to write super-fast file-streaming code in C#?