How can I check if hyperthreading is enabled on a Linux machine, using a perl script to check for it?
I'm trying the following way:
dmidecode -t processor | grep HTT
Let me know if I'm on right track.
How can I check if hyperthreading is enabled on a Linux machine, using a perl script to check for it?
I'm trying the following way:
dmidecode -t processor | grep HTT
Let me know if I'm on right track.
I have always just used the following and looked at 'Thread(s) per core:'.
hostname:~ # lscpu
Architecture: x86_64
CPU(s): 24
Thread(s) per core: 2 <-- here
Core(s) per socket: 6
CPU socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 44
Stepping: 2
CPU MHz: 1596.000
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 12288K
Note, however, this technique will fail if any logical processor has been turned off with a simple
echo 0 > /sys/devices/system/cpu/cpuX/online
echo 0 > /sys/devices/system/cpu/cpu31/online
, now lscpu reports Thread(s) per core: 1
. Bad lscpu
! Guess I won't be using this any more.
– Mike S
Oct 26 '17 at 14:07
Notes added on July 8, 2014: As Riccardo Murri pointed out, my answer below only shows whether the processor reports to support hyperthreading. Generally, *nix O/S are configured to enable hyperthreading if supported. However, to actually check this programmatically see for instance Nils' answer!
---- Original answer from March 25, 2012:
You are indeed on the right track :) with
dmidecode -t processor | grep HTT
On Linux, I generally just look for "ht" on the "flags" line of /proc/cpuinfo
. See for instance
grep '^flags\b' /proc/cpuinfo | tail -1
or if you want to include the "ht" in the pattern
grep -o '^flags\b.*: .*\bht\b' /proc/cpuinfo | tail -1
(\b
matches the word boundaries and helps avoid false positives in cases where "ht" is part of another flag.)
lscpu
is the way to check.
– sudo
Mar 17 '17 at 07:15
dmidecode
; the CPUID
flag represented by ht
means “that the physical package is capable of supporting Intel Hyper-Threading Technology and/or multiple cores”, not that the CPU supports hyper-threading.
– Stephen Kitt
Feb 12 '20 at 10:15
If the number of logical processors is twice the number of cores you have HT. Use to following script to decode /proc/cpuinfo:
#!/bin/sh
CPUFILE=/proc/cpuinfo
test -f $CPUFILE || exit 1
NUMPHY=`grep "physical id" $CPUFILE | sort -u | wc -l`
NUMLOG=`grep "processor" $CPUFILE | wc -l`
if [ $NUMPHY -eq 1 ]
then
echo This system has one physical CPU,
else
echo This system has $NUMPHY physical CPUs,
fi
if [ $NUMLOG -gt 1 ]
then
echo and $NUMLOG logical CPUs.
NUMCORE=`grep "core id" $CPUFILE | sort -u | wc -l`
if [ $NUMCORE -gt 1 ]
then
echo For every physical CPU there are $NUMCORE cores.
fi
else
echo and one logical CPU.
fi
echo -n The CPU is a `grep "model name" $CPUFILE | sort -u | cut -d : -f 2-`
echo " with`grep "cache size" $CPUFILE | sort -u | cut -d : -f 2-` cache"
$NUMCORE > $NUMLOG
we can say that hyperthreading is enabled, right? It fact it would be 2 * $NUMCORE = $NUMLOG
, is this always true or some CPUs might have 4x more cores?
– Tombart
Mar 13 '16 at 17:24
lscpu
available, lscpu
will provide the same information along with lots of extra meta-data and the output from lscpu
is more easily parseable. but this solution does work and only uses /proc/cpuinfo
.
– Trevor Boyd Smith
Jan 02 '19 at 13:20
The easiest way to check if SMT (generic for HT, which is just Intel branding) is active just do:
cat /sys/devices/system/cpu/smt/active
gives you 0 for inactive or 1 for active
You can actually turn it on or off at runtime with:
echo [on|off] > /sys/devices/system/cpu/smt/control
/sys/devices/system/cpu/smt/control
is also possible and yields on|off|forceoff|notsupported|notimplemented
.
– maxschlepzig
Aug 24 '19 at 15:08
The above examples show if the CPU is capable of HT, but not if it is being used.
The last method works but not dual socket servers and VMs tested on Xenserver
where it doesn’t display Physical CPU, since there are none.
I found this to be the easiest and less code way, which also worked on all my test environments. but requires bc
.
echo "testing ################################### "
nproc=$(grep -i "processor" /proc/cpuinfo | sort -u | wc -l)
phycore=$(cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed s/physical/\\nphysical/g | grep -v ^$ | sort | uniq | wc -l)
if [ -z "$(echo "$phycore *2" | bc | grep $nproc)" ]
then
echo "Does not look like you have HT Enabled"
if [ -z "$( dmidecode -t processor | grep HTT)" ]
then
echo "HT is also not Possible on this server"
else
echo "This server is HT Capable, However it is Disabled"
fi
else
echo "yay HT Is working"
fi
echo "testing ################################### "
I believe this will work on all platforms, and will tell you if its CPU is capable, and if it is enabled. May be a little messy, I'm a beginner at scripting though. I tested with centos XENSERVER vm, Ubuntu, and Openfiler (rpath)
/sys/devices/system/cpu/smt/control
. See also Oscar's answer
– maxschlepzig
Aug 24 '19 at 15:24
If you read /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
, it will return a comma-separated list of the thread siblings (i.e. Hyperthread "cores") of CPU 0.
For instance, on my 2-socket 6-core Xeon, with hyperthreading enabled I get:
cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0,12
But after turning off hyperthreading in BIOS, I get:
cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0
Assuming that CPU 0 will always be available, then checking CPU 0's thread_sibling_list
procfs file for more than one node, or looking for a comma, or even just anything more than 0
, will indicate if hyperthreading is enabled.
I'd answer in Perl, but 1) I don't know Perl, and 2) I assume the solution is a pretty trivial one-liner.
-
and not ,
e.g. $cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list 0-1
– Shmil The Cat
Jun 30 '22 at 10:06
This one liner seems to do the trick for me (requires root privileges):
dmidecode -t processor | grep -E '(Core Count|Thread Count)'
The output is:
Core Count: 2
Thread Count: 4
Thread count is double the core count, therefore I have hyperthreading enabled.
Or if you really want your perl script, as requested...
perl -e 'print grep(/Core Count/ || /Thread Count/, `dmidecode -t processor`);'
dmidecode
is reliable.
– Mike S
Dec 01 '16 at 23:06
lscpu
will not always be reliable. I like scottbb's answer.
– Mike S
Oct 26 '17 at 14:34
perl -ne'
$i++ if /^\s*$/;
push @{$x[$i]}, [/^(.+?) \s*:\s* (.+)/x] if /core|sibling|physical id/; }{
$r= shift @x;
for $i (0..$#$r) {
$$r[$i][1] .= " ".$$_[$i][1] for @x;
printf "%-15s: %s\n", @{$$r[$i]};
}
' /proc/cpuinfo
This result indicates that HT is enabled as siblings
number (12) is greater than cpu cores
(6)
physical id : 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1
siblings : 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12
core id : 0 1 2 8 9 10 0 1 2 8 9 10 0 1 2 8 9 10 0 1 2 8 9 10
cpu cores : 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
On Linux this works well:
$ lscpu -e
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
0 0 0 0 0:0:0:0 yes
1 0 0 1 1:1:1:0 yes
2 0 0 2 2:2:2:0 yes
3 0 0 3 3:3:3:0 yes
4 0 0 4 4:4:4:0 yes
5 0 0 5 5:5:5:0 yes
6 0 0 6 6:6:6:0 yes
7 0 0 7 7:7:7:0 yes
8 1 1 8 8:8:8:1 yes
9 1 1 9 9:9:9:1 yes
10 1 1 10 10:10:10:1 yes
11 1 1 11 11:11:11:1 yes
12 1 1 12 12:12:12:1 yes
13 1 1 13 13:13:13:1 yes
14 1 1 14 14:14:14:1 yes
15 1 1 15 15:15:15:1 yes
16 0 0 0 0:0:0:0 yes
17 0 0 1 1:1:1:0 yes
18 0 0 2 2:2:2:0 yes
19 0 0 3 3:3:3:0 yes
20 0 0 4 4:4:4:0 yes
21 0 0 5 5:5:5:0 yes
22 0 0 6 6:6:6:0 yes
23 0 0 7 7:7:7:0 yes
24 1 1 8 8:8:8:1 yes
25 1 1 9 9:9:9:1 yes
26 1 1 10 10:10:10:1 yes
27 1 1 11 11:11:11:1 yes
28 1 1 12 12:12:12:1 yes
29 1 1 13 13:13:13:1 yes
30 1 1 14 14:14:14:1 yes
31 1 1 15 15:15:15:1 yes
In the above example, we have 2 NUMA sockets (SOCKET=1 or 2). We have 16 physical cores (CORE=0 through 15). Each CORE has a sibling hyperthread (For example CORE=0 contains CPU 0,16.
We can verify the hyperthread like so:
$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0,16
The cache memory hierarchy is:
CPU 0 --> L1D_0|L1I_0 -> L2_0 -> L3_0
^ ^
CPU 16 ---| |
|
CPU 1 --> L1D_1|L1I_1 -> L2_1 --->
^
CPU 17 ---|
...
lscpu -p gives a csv format output for easy program parsing.
$ lscpu -p
# The following is the parsable format, which can be fed to other
# programs. Each different item in every column has an unique ID
# starting from zero.
# CPU,Core,Socket,Node,,L1d,L1i,L2,L3
0,0,0,0,,0,0,0,0
1,1,0,0,,1,1,1,0
2,2,0,0,,2,2,2,0
3,3,0,0,,3,3,3,0
4,4,0,0,,4,4,4,0
...
You can check HT capability of CPU with this command
# grep ht /proc/cpuinfo
You can list physical and logiciel CPU seen by Kernel with the following command:
# egrep -i "processor|physical id" /proc/cpuinfo
It gives this output on a single-core HT enabled CPU:
processor : 0
physical id : 0
processor : 1
physical id : 0
You can read the result like this:
processor : 0 (CPU 0, first logical)
physical id : 0 (CPU 0 is on the first physical)
processor : 1 (CPU 1, second logical)
physical id : 0 (CPU 1 is on the first physical)
=> It means I have HT enabled
ht
in the CPU flags.
– Riccardo Murri
Apr 23 '14 at 18:01
physical id
seems to represent the socket/chip. The core id
seems to point to the same physical core
– Chang Hyun Park
Jul 08 '15 at 03:11
Lot's of caveats and what-if's in the answers here... it seems the answer is not so obvious. lscpu
has its gotcha's, which apply to any "count cores and logical processors, then compare" answer. Because you can shut off logical processors with a simple echo command (...this could be critical in a large enterprise environment where you're depending on turbo mode, for example).
Here's my try; thanks to @scottbb for the inspiration:
printf "HT is "; egrep -q [:punct:] /sys/devices/system/cpu/cpu0/topology/thread_siblings_list && echo on || echo off
On my Dell Xeon-based machines, the sibling list includes a comma when HT is on. On my laptop, it includes a hyphen (i5-3210m processor). So I'm egrep'ing for punctuation.
Thoughts? Criticisms?
The requester asked for perl, so here you go:
perl -ane 'chomp; print "Hyperthreading is "; if (/\D/) { print "ON\n" } else { print "OFF\n" }' < /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
grep -q [-.]
as this is less to type. FWIW, I've checked several Xeons/i5/i7's (including mobile variants) and none of them have a hyphen in the thread_siblings_list
. It isn't sufficient to just check cpu0 - thus, something like this would be more robust: grep -q , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list
. However, just a grep 1 /sys/devices/system/cpu/smt/active -q
is even more to the point - cf. Oscar's answer
– maxschlepzig
Aug 24 '19 at 15:04
lscpu | grep Thread
Returns -> Thread(s) per core: 1
If 1 hyper threading is NOT enabled.
Here's a python based approach - it also suggests ways to disable it if needed.
import re
total_logical_cpus = 0
total_physical_cpus = 0
total_cores = 0
logical_cpus = {}
physical_cpus = {}
cores = {}
hyperthreading = False
for line in open('/proc/cpuinfo').readlines():
if re.match('processor', line):
cpu = int(line.split()[2])
if cpu not in logical_cpus:
logical_cpus[cpu] = []
total_logical_cpus += 1
if re.match('physical id', line):
phys_id = int(line.split()[3])
if phys_id not in physical_cpus:
physical_cpus[phys_id] = []
total_physical_cpus += 1
if re.match('core id', line):
core = int(line.split()[3])
if core not in cores:
cores[core] = []
total_cores += 1
cores[core].append(cpu)
if (total_cores * total_physical_cpus) * 2 == total_logical_cpus:
hyperthreading = True
print(" This system has %d physical CPUs" % total_physical_cpus)
print(" This system has %d cores per physical CPU" % total_cores)
print(" This system has %d total cores" % (total_cores * total_physical_cpus))
print(" This system has %d logical CPUs" % total_logical_cpus)
if hyperthreading:
print(" HT detected, if you want to disable it:")
print(" Edit your grub config and add 'noht'")
print(" -OR- disable hyperthreading in the BIOS")
print(" -OR- try the following to offline those CPUs:")
for c in cores:
for p, val in enumerate(cores[c]):
if p > 0:
print(" echo 0 > /sys/devices/system/cpu/cpu%d/online" % (val))
echo off > /sys/devices/system/cpu/smt/control
(besides turning it off in the bios). See also Oscar's answer for a direct check.
– maxschlepzig
Aug 24 '19 at 15:20
Stephaniea has already mentioned lscpu
. I wanted to add a bit more to that.
On my AMD Epyc Processor, whenever there is an offline logical core, lscpu
displays a new additional line called Off-line CPU(s) list:
# echo 0 > /sys/devices/system/cpu/cpu9/online
# echo 0 > /sys/devices/system/cpu/cpu16/online
#
#lscpu
CPU(s): 64
On-line CPU(s) list: 0-8,10-15,17-63
Off-line CPU(s) list: 9,16
Better you check lscpu, where you can see "Thread(s) per core: 1", means only one thread per 1 core.
# 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
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2623 v3 @ 3.00GHz
Stepping: 2
CPU MHz: 1200.000
BogoMIPS: 5992.82
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 10240K
NUMA node0 CPU(s): 0,1,4,5
NUMA node1 CPU(s): 2,3,6,7
dmidecode
you have to be root. – Nils Mar 05 '12 at 20:50[perl]
unset ^^ – Artfaith Nov 14 '23 at 13:08