49

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.

  • 2
    for dmidecode you have to be root. – Nils Mar 5 '12 at 20:50
  • 4
    I like how everyone ignored the "perl script" bit ;-) – SamB May 30 '14 at 20:32

15 Answers 15

25

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.)

  • 18
    This will only tell you if the processor is HT capable, not if HT is actually being used. – Riccardo Murri Apr 23 '14 at 18:00
  • 3
    the HTT field does not indicate that the processor is actually having hyperthreading in its cores. check the value of 'siblings' and 'cpu cores' in /proc/cpuinfo – Silver Moon Jun 29 '14 at 9:05
  • @Silver-Moon Can you explicate? dmidecode reads the SMBIOS and should tell the capabilities of the processor. It does not tell whether hyper-threading is seen or used by the O/S. But this has already been commented on. See also Nils answer – xebeche Jul 3 '14 at 19:09
  • 1
    @xebeche on my system dmidecode output shows "HTT (Multi-threading)" but my processor is "core 2 quad Q8400" which does not have hyperthreading. check intel specifications. – Silver Moon Jul 4 '14 at 3:13
  • 1
    +1 to Riccardo; I have HT disabled on an HT-capable server, and I see it print "HTT". lscpu is the way to check. – sudo Mar 17 '17 at 7:15
92

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
  • 3
    This is the best answer yet. It requires no reading of the tea leaves, lots of helpful information, and no grepping required. – MrMas Dec 11 '15 at 19:48
  • 10
    OMG you used a shell command to get your answer?! That's so old-school- -1 for that. What about a nice Python script??? It would only take you an afternoon to write. Since it's not Python, another -1. But +3 for brevity. – Mike S Aug 5 '16 at 20:06
  • @Mike S lots of sarcasm but... The output of lscpu ain't correct when, say, only 1 hyper-threaded core is down on a 4 cores CPU (which is a fully valid scenario). Because then it'll report "Thread(s) per core: 1" although 3 cores are actually hyperthreaded (7 threads in total). – Cedric Martin Oct 25 '17 at 23:15
  • @Cedric Martin you noticed. :-) ...Oooo! Good catch... I did it! Took a dual 8-core machine (Dell R620/E5-2667 v2 CPU)... it reports 32 CPUs... Performed 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
  • 3
    @Mike S You can still use lscpu, but just not that line I guess. Using, say, "lscpu -e -a" correctly list each thread and tells if it's active or not. It's just that "Thread(s) per core" doesn't make much sense when you can enable/disable threads differently on each core. – Cedric Martin Oct 26 '17 at 21:03
18

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"
  • If $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
  • @Tombart Currently HT is factor 2. I can imagine that it might be more in the future. A core is noted as physical. The number of cores per socket can be derived from siblings. – Nils May 5 '16 at 21:22
  • If you have 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 2 at 13:20
7

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)

I have a similar cool script here, would like to see what you think?

7

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
  • This will only tell you if the processor is HT capable, not if HT is actually being used. Nodes whose processor is HT-capable but where HT is not enable will still advertise ht in the CPU flags. – Riccardo Murri Apr 23 '14 at 18:01
  • @RiccardoMurri As far as I know, when HT is disabled, ht flag does not appear in /proc/cpuinfo – Coren Apr 24 '14 at 9:48
  • 5
    I'm pretty sure it's not. I have both HT-enabled and HT-disabled servers, and all of them show the ht flag. – Riccardo Murri Apr 25 '14 at 10:32
  • 2
    If you have a Xeon processor with 4 cores, it will show as one physical id and four processors. So you can have multiple processors per physical id without hyperhtreading. – Andomar Nov 9 '14 at 11:39
  • 2
    I've got a 2 socket machine, and the physical id seems to represent the socket/chip. The core id seems to point to the same physical core – Heartinpiece Jul 8 '15 at 3:11
6

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`);'
  • I have HT turned off on an Intel based HT capable system, yet Thread Count returned with dmidecode is twice the Core Count. Looks like it shows if the CPU is HT capable, not if HT is enabled or not. – Dmitri Chubarov Dec 16 '15 at 13:58
  • @Dmitri Weird. I just ran this on an HT-capable server (has two Intel Xeon E5-2670 v3's) with hyperthreading disabled, and the core and thread count were the same. I'm not sure what would cause the difference in behavior. I'll have to look further into it. – billyw May 26 '16 at 17:10
  • I just ran this on a Dell R610 with two X5680 processors, Hyperthreading off, and the Thread count is double the core count. stephaniea's answer (lscpu) seems to work. I have doublechecked the iDRAC (Dell's lights-out, out of band processor [for those not in the know]) and it says that Hyperthreading is off. So I don't think dmidecode is reliable. – Mike S Dec 1 '16 at 23:06
  • I checked a Dell 1950 (x5460 CPUs, no hyperthreading possible) and lscpu was correct. Also a Dell R620 (E5-2690 [v1, I believe]) and it was correct. – Mike S Dec 1 '16 at 23:13
  • But @Cedric Martin 's comment in one of the answers above shows that lscpu will not always be reliable. I like scottbb's answer. – Mike S Oct 26 '17 at 14:34
3
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
2

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.

2

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
...
2

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))
1

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
0

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
0

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
0

how about lscpu. Then you get a lot of information about your cpu's including the number of threads per core. If that's 1 than multithreading is off.

  • 1
    This is already mentioned in other answers. – Stephen Kitt May 23 at 20:08
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.