[SOLVED] Which core frequencies correspond to physical cores in /proc/cpuinfo?

So, I understand that in /proc/cpuinfo, all the threads are equally “real.” But I can’t see how that would be true for core frequencies. Two threads on the same physical core should always have the same frequency, so I should have at most 16 unique frequencies.

~$ grep MHz /proc/cpuinfo | sort
cpu MHz		: 1917.721
cpu MHz		: 1972.656
cpu MHz		: 2003.990
cpu MHz		: 2008.664
cpu MHz		: 2043.138
cpu MHz		: 2046.547
cpu MHz		: 2191.673
cpu MHz		: 2389.479
cpu MHz		: 2415.510
cpu MHz		: 2537.163
cpu MHz		: 2728.098
cpu MHz		: 2728.222
cpu MHz		: 2767.258
cpu MHz		: 2786.828
cpu MHz		: 2847.442
cpu MHz		: 2973.655
cpu MHz		: 3007.269
cpu MHz		: 3154.297
cpu MHz		: 3325.515
cpu MHz		: 3590.166
cpu MHz		: 3612.830
cpu MHz		: 3771.714
cpu MHz		: 4074.337
cpu MHz		: 4079.972
cpu MHz		: 4091.239
cpu MHz		: 4091.646
cpu MHz		: 4092.344
cpu MHz		: 4092.348
cpu MHz		: 4092.358
cpu MHz		: 4092.358
cpu MHz		: 4092.368
cpu MHz		: 4092.370
~$ 

There are 32 frequencies listed here, all different from each other, but I only have 16 physical cores. How do I know which frequencies are real? And is there a scriptable way to determine it?

Most Linux CPU frequency monitoring software also shows a frequency for each thread, so it seems like most of them haven’t accounted for SMT either.

Welcome to the forums!

Freqs change very fast, so maybe when cpuinfo grabbed whatever it grabs for one thread, the freq changed by the time it grabbed the next thread.

Here’s mine, for comparison. I have the scheduler set to “throughput-performance” using tuned. (water cooled 2950x)

~]$ grep MHz /proc/cpuinfo | sort
cpu MHz         : 4089.037
cpu MHz         : 4090.812
cpu MHz         : 4091.693
cpu MHz         : 4091.763
cpu MHz         : 4091.766
cpu MHz         : 4091.774
cpu MHz         : 4091.775
cpu MHz         : 4091.780
cpu MHz         : 4091.789
cpu MHz         : 4091.796
cpu MHz         : 4091.802
cpu MHz         : 4091.812
cpu MHz         : 4091.815
cpu MHz         : 4091.824
cpu MHz         : 4091.846
cpu MHz         : 4091.846
cpu MHz         : 4091.847
cpu MHz         : 4091.848
cpu MHz         : 4091.854
cpu MHz         : 4091.854
cpu MHz         : 4091.858
cpu MHz         : 4091.860
cpu MHz         : 4091.861
cpu MHz         : 4091.861
cpu MHz         : 4091.862
cpu MHz         : 4091.862
cpu MHz         : 4091.863
cpu MHz         : 4091.863
cpu MHz         : 4091.864
cpu MHz         : 4091.865
cpu MHz         : 4091.865
cpu MHz         : 4091.866

I decided to try some experiments with CPU affinity. I loaded one thread at a time with a synthetic load using

taskset -c 1 stress -c 1

Where I could change the taskset argument to pick which thread I was loading.

Then, I tried to identify any threads that were listed with a frequency above 4 GHz:

egrep '(processor)|(MHz)' /proc/cpuinfo | egrep -B 1 $'MHz\t+: 4'

Because other cores are turboing up and down all the time, this requires a few repeats to be sure you’ve identified the cores. Here are my results though:

Loaded Thread       Boosting Threads
0                   0, 16
1                   1, 17
2                   2, 18
5                   5, 21
12                  12, 28
16                  0, 16
17                  1, 17
25                  9, 25
28                  12, 28
31                  15, 31

Even though the frequencies never agreed with each other exactly, these threads are clearly paired together with an offset of 16 betwewen them. So I think you are right about what’s happening.

1 Like

For the scriptability aspect, lscpu can generate a JSON report of which threads belong to which cores:

~$ lscpu -Je=core
{
   "cpus": [
      {"core":"0"},
      {"core":"1"},
      {"core":"2"},
      {"core":"3"},
      {"core":"4"},
      {"core":"5"},
      {"core":"6"},
      {"core":"7"},
      {"core":"8"},
      {"core":"9"},
      {"core":"10"},
      {"core":"11"},
      {"core":"12"},
      {"core":"13"},
      {"core":"14"},
      {"core":"15"},
      {"core":"0"},
      {"core":"1"},
      {"core":"2"},
      {"core":"3"},
      {"core":"4"},
      {"core":"5"},
      {"core":"6"},
      {"core":"7"},
      {"core":"8"},
      {"core":"9"},
      {"core":"10"},
      {"core":"11"},
      {"core":"12"},
      {"core":"13"},
      {"core":"14"},
      {"core":"15"}
   ]
}

Wouldn’t take much to do lookups in the opposite direction and grab only the cpuinfo entries for the physical core you’re interested in.