Detecting whether hyperthreading is enabled

We’ve recently had requests for our internal inventory to flag which systems have hyperthreading enabled and which don’t. This brought up the question of what’s the simplest and most universal way to detect if a given Linux server has hyperthreading enabled. The expected google searches turned up a lot of discussion but not a lot of definitive answers. With this post I’d like to offer three different tests I have found, and also open for discussion how reliable and universal these tests are, and if there are perhaps better alternatives.

The most common answer was to check the values of ‘cpu cores’ and ‘siblings’ in /proc/cpuinfo. When hyperthreading is enabled, those values should be different for each logical processor:

From a server with hyperthreading enabled:
# egrep 'siblings|cpu cores' /proc/cpuinfo | head -2
siblings : 8
cpu cores : 4

This seemed to be fairly reliably true even for much older legacy systems that I sampled, but I couldn’t think of a very simple single-command line to boil this test down to. I imagine something could be built with perl or awk, for example but I couldn’t think of a way that didn’t turn into a fairly unwieldily command to be executing remotely.

The next test I ran across was to check the value of thread_siblings_list in /sys. Experimentally, I observed over a few systems that I could reduce this check down to whether or not there was a comma in /sys/devices/system/cpu/cpu0/topology/thread_siblings_list. This had the advantage of theoretically turning the entire test into a simple grep statement:

# grep ',' /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
0,8

But then I found that thread_siblings_list didn’t exist on some of my older legacy servers such as those running openSuse 10.2.

The last test I determined so far seems to be more universal (though I cannot really confirm it without a lot more sampling or some more detailed documentation than I can find in the kernel’s Documentation/cputopology.txt file). That test checks to see if the thread_siblings pseudo-file ends with ‘,00000001’. Sample tests suggest that file always ends with that value on non-hyperthreaded systems.

The same hyperthread-enabled server again, this time no match and no output:

# egrep ',00000001$' /sys/devices/system/cpu/cpu0/topology/thread_siblings
#

Whereas on other servers without hyperthreading, I get results like this:

# egrep ',00000001$' /sys/devices/system/cpu/cpu0/topology/thread_siblings
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001

The number of items in the returned list appears to vary by architecture and number of cores/cpus, but I couldn’t find any systems so far where this test failed to work as expected. So far I’ve only tested this on openSuse 10.2, 11,1, and 11.4, and Fedora 15.

I’d love to hear of any corrections or better alternative methods for simply and reliably detecting the status of hyperthreading with a simple shell command.