How to Find My CPU Topology

How do I find my CPU topology?

you can use command

lscpu

this will give information

for processor related info

dmidecode -t processor

Linux find out Hyper-threaded core id

I discovered the simply trick to do what I need.

cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list

If the first number is equal to the CPU number (0 in this example) then it's a real core, if not it is a hyperthreading core.

Real core example:

# cat /sys/devices/system/cpu/cpu1/topology/thread_siblings_list
1,13

Hyperthreading core example

# cat /sys/devices/system/cpu/cpu13/topology/thread_siblings_list
1,13

The output of the second example is exactly the same as the first one. However we are checking cpu13, and the first number is 1, so CPU 13 this is an hyperthreading core.

How do I find information about the parallel architecture of my CPU?

The sys filesystem knows all about this:

$ ls /sys/devices/system/cpu 
cpu0 cpu2 cpuidle possible sched_mc_power_savings
cpu1 cpu3 online present

$ ls /sys/devices/system/cpu/cpu0/topology/
core_id core_siblings_list thread_siblings
core_siblings physical_package_id thread_siblings_list

Here's the documentation

Using this filesystem, you can find out how many CPUs you have, how many threads they have, which CPUs are next to which other cpus, and which CPUs share caches with which other ones.

For example - Q: which CPUs does cpu0 share it's L2 cache with?

$ cat /sys/devices/system/cpu/cpu0/cache/index2/{type,level,shared_cpu_list}
Unified
2
0-1

A: It shares it's unified L2 cache with cpu1 (and itself).

Another example: Q: which CPUs are in the same physical package as cpu0 (on a larger machine):

cat /sys/devices/system/cpu/cpu0/topology/core_siblings
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000055

A: cores 0, 2, 4 and 6. (taken from the bit pattern above, lsb=cpu0)


not all linux systems have the sys filesystem in, and it's not always in root. (possibly in proc/sys?). the thread_siblings_list form is not always available, but the thread_siblings (bit pattern) one is.

Detecting CPU and Core information from my Intel System

From the perspective of your operating system, even HyperThreaded processors are "real" processors - they exist in the CPU. They use real, physical resources like instruction decoders and ALUs. Just because those resources are shared between HT cores doesn't mean they're not "real".

General computing will see a speedup by using Hyper Threading, because the various threads are doing different kinds of things, leveraging the shared resources. A CPU-intensive task running in parallel may not see as high of performance however, due to the strain on the shared resources. For example, if there's only one ALU, it doesn't make sense to have two threads competing for it.

Run benchmarks and determine for your application what the appropriate settings are, regarding HT being enabled or not. With a question this broad, we can't give you a definitive answer.

how can i get the cpu_id that my erlang vm is hosting on?

Judging from comments to johlo's answer, you are running Erlang on Linux without SMP and with taskset.

The multi-platform code for handling CPU binding and affinity is in erl_misc_utils.c. Erlang currently supports binding of scheduler threads on newer Linux, Windows, Solaris (and derived OSes with kstat) and FreeBSD. This is why erlang:system_info(cpu_topology) returns undefined on MacOS X. Yet, it works on your Linux distribution as reported in comments.

On Linux, taskset sets the CPU affinity of the subprocess. Yet, Erlang directly gets available CPUs from /sys/devices/system, and this ignores the current affinity. So by using taskset, you are fooling Erlang which, in SMP mode, might try to bind schedulers without success.

Besides, it seems the only way to know about the forced CPU affinity with taskset would be to get the CPU affinity. Which the Erlang VM does not seem to expose through any API. It seems that function erts_get_available_cpu which queries the OS for CPU affinity is not even called.

I can see two solutions to your specific problem:

  • since you are using taskset, you could pass some information (e.g. a configuration value) on the command line to tell your apps on which CPU they are running;
  • alternatively, instead of taskset, you could use Erlang's ability to bind schedulers and provide
    your VM with a partial CPU topology of a single core. This trick is actually described in the documentation of +sct option. Then, using erlang:system_info(cpu_topology) or erlang:system_info(scheduler_bindings) will tell you which processor Erlang is currently running on.

This second solution is of course cleaner and more portable, although it will not work on some platforms as mentioned above. Please note that this might require to run Erlang in SMP mode, but a proper user defined topology with a single logical processor will make Erlang start a single scheduler. You can also pass +S 1:1 which is portable.

Is there a standard format for /sys/devices/system/cpu/cpu0/topology/thread_siblings_list?

There doesn't seem to be an documented way but turbostat, an internal program and part of linux-tools, expects the format to be:

A number, followed by any character as seperator, ..., the last number.

The current version is here.

/*
* get_cpu_position_in_core(cpu)
* return the position of the CPU among its HT siblings in the core
* return -1 if the sibling is not in list
*/
int get_cpu_position_in_core(int cpu)
{
char path[64];
FILE *filep;
int this_cpu;
char character;
int i;

sprintf(path,
"/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list",
cpu);
filep = fopen(path, "r");
if (filep == NULL) {
perror(path);
exit(1);
}

for (i = 0; i < topo.num_threads_per_core; i++) {
fscanf(filep, "%d", &this_cpu);
if (this_cpu == cpu) {
fclose(filep);
return i;
}

/* Account for no separator after last thread*/
if (i != (topo.num_threads_per_core - 1))
fscanf(filep, "%c", &character);
}

fclose(filep);
return -1;
}

How to obtain the number of CPUs/cores in Linux from the command line?

grep -c ^processor /proc/cpuinfo

will count the number of lines starting with "processor" in /proc/cpuinfo

For systems with hyper-threading, you can use

grep ^cpu\\scores /proc/cpuinfo | uniq |  awk '{print $4}'

which should return (for example) 8 (whereas the command above would return 16)



Related Topics



Leave a reply



Submit