Tuesday, August 13, 2019

How to disable or enable hyper threading on linux?

Hyper threading uses processor resources more efficiently, enabling multiple threads to run
on each core. As a performance feature, it also increases processor throughput, improving
overall performance on threaded software. A single physical CPU core with hyper-threading
appears as two logical CPUs to an operating system.

The recommended way to disable HT is by disabling in the BIOS, if possible but this can
also be done via operating system using the below steps.


Disable HT on runtime for individual logical CPUs
Before starting let's check the lscpu stat

# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                32
On-line CPU(s) list:   0-31
Thread(s) per core:    2
Core(s) per socket:    8
Socket(s):             2


Here it shows that there are 2 threads per core so we know most likely hyper threading is
enabled


The following files will show all of the logical CPU's and their HT pair relationships
# grep -H . /sys/devices/system/cpu/cpu*/topology/thread_siblings_list

To determine which CPUs should be disabled, the threads running on the same CPU core
have to be identified. The files /sys/devices/system/cpu/cpuN/topology/thread_siblings_list
where N is the CPU socket number. This file will contain the logical (HT) CPU numbers for
each physical socket.

# grep -H . /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | sort -n -t ',' -k 2 -u
/sys/devices/system/cpu/cpu0/topology/thread_siblings_list:0,16
/sys/devices/system/cpu/cpu17/topology/thread_siblings_list:1,17
/sys/devices/system/cpu/cpu18/topology/thread_siblings_list:2,18
/sys/devices/system/cpu/cpu19/topology/thread_siblings_list:3,19
/sys/devices/system/cpu/cpu20/topology/thread_siblings_list:4,20
/sys/devices/system/cpu/cpu21/topology/thread_siblings_list:5,21
/sys/devices/system/cpu/cpu22/topology/thread_siblings_list:6,22
/sys/devices/system/cpu/cpu23/topology/thread_siblings_list:7,23
/sys/devices/system/cpu/cpu24/topology/thread_siblings_list:8,24
/sys/devices/system/cpu/cpu25/topology/thread_siblings_list:9,25
/sys/devices/system/cpu/cpu10/topology/thread_siblings_list:10,26
/sys/devices/system/cpu/cpu11/topology/thread_siblings_list:11,27
/sys/devices/system/cpu/cpu12/topology/thread_siblings_list:12,28
/sys/devices/system/cpu/cpu13/topology/thread_siblings_list:13,29
/sys/devices/system/cpu/cpu14/topology/thread_siblings_list:14,30
/sys/devices/system/cpu/cpu15/topology/thread_siblings_list:15,31

This means that CPU0 and CPU16 are threads on the same core. The same for 1 and 17
and so on. Individual, logical HT CPUs could be turned off as needed for a specific
application that is bound to a physical core.


Or the following script would disable all of them, from logical CPU 16 through 31

# cat /tmp/disable_ht.sh
#!/bin/bash
for i in {16..31}; do
   echo "Disabling logical HT core $i."
   echo 0 > /sys/devices/system/cpu/cpu${i}/online;
done

To disable individual logical CPU use the below command and replace <cpu_id> with the id from (16..31)
echo 0 > /sys/devices/system/cpu/<cpu_id>/online

To re-enable the HT

# cat /tmp/enable_ht.sh
for i in {16..31}; do
   echo "Enabling logical HT core $i."
   echo 1 > /sys/devices/system/cpu/cpu${i}/online;

done