5

My application requires maximum single-thread performance and suffers from switching to the Intel E cores.

I am looking for a way to disable E cores on Intel i9-12900K on my Ubuntu 20.04 machine without access to bios (it is a rented dedicated server). Or for any possible way to distinguish such cores and assign CPU affinities using taskset to exclude them from execution.

Tried to find the answer myself in Google. Only found that there are indeed scheduler issues for now, but there is no clear fixes or workarounds available for my problem.

Radiant
  • 53
  • 1
    Stupid brute-force workaround: run some test program once for each core, locked to that one core. Any differences between them should show up in the results, and then you can use that to set the cpu affinity for good. – ilkkachu Jan 15 '22 at 11:50
  • 1
    @ilkkachu I've just did this right when you commented. I run 7z benchmark on one thread for each core and used taskset: taskset -c CORE_ID 7z b -mmt1. Now I know that the last 8 cores are efficiency cores, they have 20-25% less MIPS. But I think that it is not very elegant solution and there may be some people who know more. – Radiant Jan 15 '22 at 11:52

3 Answers3

9

taskset is a standard feature to assign cores to applications which works perfectly in your situation. E.g. in the case of Intel Core i9 12900K pin your task to the first sixteen cores and you're good to go:

taskset 0xFFFF application
taskset -c 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 application

The second form is longer but easier to read.

AFAIK the standard Linux kernel doesn't currently have any infrastructure to hint the kernel that certain applications need to use certain types of cores. Yes, the Linux kernel supports BIG.little ARM architectures but I've not heard of API to utilize this feature.

As of January, 2022 the Linux kernel does not support Intel Thread Director in any shape or form. There have been no patches, nothing.

Lastly, it's worth noting that Linux and Windows differ in how they report HT/SMT siblings.

Windows lists them in pairs, i.e. Core 1: Thread 1 Thread 2, Core 2: Thread 1 Thread 2, etc. Linux first lists all physical cores, then their HT/SMT siblings.

So, if you want to test physical cores without using HT/SMT for a sixteen-core CPU, you'll do this:

taskset -c 0,1,2,3,4,5,6,7 application
taskset 0xFF application

More on it here: How do I know which processors are physical cores?


Option N2: you can put E cores offline, and they will become invisible for your system:

echo 0 | sudo tee /sys/devices/system/cpu/cpu{NN}/online

For Intel Core i9 12900K that'll be

for i in {16..23}; do echo 0 | sudo tee /sys/devices/system/cpu/cpu${i}/online; done
4

Instead of disabling e-cores entirely, use isolcpus boot parameter to isolate e-cores from the general scheduler.

For example, in case of Intel Core i9 12900K:

$ sudo vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=16,17,18,19,20,21,22,23"    

$ sudo update-grub

You can then still use e-cores by manually assigning them to specific processes using taskset or cset:

$ sudo taskset -p 0xFF0000 <pid>

Alternatively, can also use cset shield.

rustyx
  • 319
0

You may also use chcpu -d [cpulist] to bring cores offline at any time.

See man chcpu