命令行中的处理器/核数

我正在运行以下命令来获取 Linux 中的处理器/核的数量:

cat /proc/cpuinfo | grep processor | wc -l

它有效,但看起来不够优雅。你建议如何改进它?

107964 次浏览

I think the method you give is the most portable on Linux. Instead of spawning unnecessary cat and wc processes, you can shorten it a bit:

$ grep --count ^processor /proc/cpuinfo
2

On newer kernels you could also possibly use the the /sys/devices/system/cpu/ interface to get a bit more information:

$ ls /sys/devices/system/cpu/
cpu0  cpufreq  kernel_max  offline  possible  present  release
cpu1  cpuidle  modalias    online   power     probe    uevent
$ cat /sys/devices/system/cpu/kernel_max
255
$ cat /sys/devices/system/cpu/offline
2-63
$ cat /sys/devices/system/cpu/possible
0-63
$ cat /sys/devices/system/cpu/present
0-1
$ cat /sys/devices/system/cpu/online
0-1

See the official docs for more information on what all these mean.

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)

The most simplest tool comes with glibc and is called getconf:

$ getconf _NPROCESSORS_ONLN
4

The lscpu(1) command provided by the util-linux project might also be useful:

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 58
Model name:            Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Stepping:              9
CPU MHz:               3406.253
CPU max MHz:           3600.0000
CPU min MHz:           1200.0000
BogoMIPS:              5787.10
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              4096K
NUMA node0 CPU(s):     0-3

This is for those who want to a portable way to count cpu cores on *bsd, *nix or solaris (haven't tested on aix and hp-ux but should work). It has always worked for me.

dmesg | \
egrep 'cpu[. ]?[0-9]+' | \
sed 's/^.*\(cpu[. ]*[0-9]*\).*$/\1/g' | \
sort -u | \
wc -l | \
tr -d ' '

solaris grep & egrep don't have -o option so sed is used instead.

Another one-liner, without counting hyper-threaded cores:

lscpu | awk -F ":" '/Core/ { c=$2; }; /Socket/ { print c*$2 }'

If you need an os independent method, works across Windows and Linux. Use python

$ python -c 'import multiprocessing as m; print m.cpu_count()'
16

When someone asks for "the number of processors/cores" there are 2 answers being requested. The number of "processors" would be the physical number installed in sockets on the machine.

The number of "cores" would be physical cores. Hyperthreaded (virtual) cores would not be included (at least to my mind). As someone who writes a lot of programs with thread pools, you really need to know the count of physical cores vs cores/hyperthreads. That said, you can modify the following script to get the answers that you need.

#!/bin/bash


MODEL=`cat /cpu/procinfo | grep "model name" | sort | uniq`
ALL=`cat /proc/cpuinfo | grep "bogo" | wc -l`
PHYSICAL=`cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l`
CORES=`cat /proc/cpuinfo | grep "cpu cores" | sort | uniq | cut -d':' -f2`
PHY_CORES=$(($PHYSICAL * $CORES))
echo "Type $MODEL"
echo "Processors $PHYSICAL"
echo "Physical cores $PHY_CORES"
echo "Including hyperthreading cores $ALL"

The result on a machine with 2 model Xeon X5650 physical processors each with 6 physical cores that also support hyperthreading:

Type model name : Intel(R) Xeon(R) CPU           X5650  @ 2.67GHz
Processors 2
Physical cores 12
Including hyperthreading cores 24

On a machine with 2 mdeol Xeon E5472 processors each with 4 physical cores that doesn't support hyperthreading

Type model name : Intel(R) Xeon(R) CPU           E5472  @ 3.00GHz
Processors 2
Physical cores 8
Including hyperthreading cores 8

Another portable way of doing this would be

node -p 'os.cpus().length'