Fixing Intel Meteor Lake: Less Is More
I had to replace my laptop a few months back1 and, owing to the timing, am now saddled with an extremely inconsistent Intel Meteor Lake CPU. Haha.
The problem, in a nutshell, is its fourteen cores were not created equal; they range from good (4) to less good (8) to fucking terrible (2).2
It's a curious configuration.
For many types of workloads, including my own, that variability mostly just drags down the average. The system can actually perform better without the bloat.
Thankfully, Linux makes it easy to do (and undo) just that.
Identifying the Cores.
First things first, you'll need to identify which cores are which:
lscpu --extended
#CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ
# 0 0 0 0 8:8:2:0 yes 4900.0000
# 1 0 0 0 8:8:2:0 yes 4900.0000
# 2 0 0 1 12:12:3:0 yes 4900.0000
# 3 0 0 1 12:12:3:0 yes 4900.0000
# 4 0 0 2 0:0:0:0 yes 3800.0000
# 5 0 0 3 2:2:0:0 yes 3800.0000
# 6 0 0 4 4:4:0:0 yes 3800.0000
# 7 0 0 5 6:6:0:0 yes 3800.0000
# 8 0 0 6 1:0 yes 3800.0000
# 9 0 0 7 10:10:1:0 yes 3800.0000
# 10 0 0 8 1:0 yes 3800.0000
# 11 0 0 9 14:14:1:0 yes 3800.0000
# 12 0 0 10 64:64:8 yes 2100.0000
# 13 0 0 11 66:66:8 yes 2100.0000
Note the MAXMHZ
column; the differences in maximum clock speed tell you everything you need to know:
- Cores 0-3 share the same and highest rate; they're the good ones.
- Cores 4-11 share the same and middlest rate; they're the less good ones.
- Cores 12-13 share the same and lowest rate; they're the fucking terrible ones.
Disabling CPU Cores
While yes, we are about to take CPU core(s) temporarily offline, you should think of this section as a test; you're simply checking whether or not the E-cores have been ruining your life.
Nothing done here will be permanent.
Even if you lose this page and your mind and forget to manually undo everything, it'll automatically return to the way it was after a reboot, so don't sweat it.
(The next section will show you how to make the changes permanent if the test is successful.)
With that out of the way, onto the killing!
Core #0 is special and can't be disabled, but everything else is fair game.
Still, you'll probably want to limit your focus to the terrible "efficiency" cores:3
# Disable cores 12 and 13.
sudo chcpu -d 12,13 # CHANGEME!
That command enumerates the actions taken, but you can also rerun lscpu --extended
for independent verification:
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ
0 0 0 0 8:8:2:0 yes 4900.0000
1 0 0 0 8:8:2:0 yes 4900.0000
2 0 0 1 12:12:3:0 yes 4900.0000
3 0 0 1 12:12:3:0 yes 4900.0000
4 0 0 2 0:0:0:0 yes 3800.0000
5 0 0 3 2:2:0:0 yes 3800.0000
6 0 0 4 4:4:0:0 yes 3800.0000
7 0 0 5 6:6:0:0 yes 3800.0000
8 0 0 6 1:0 yes 3800.0000
9 0 0 7 10:10:1:0 yes 3800.0000
10 0 0 8 1:0 yes 3800.0000
11 0 0 9 14:14:1:0 yes 3800.0000
12 - - - - no
13 - - - - no
Offline cores are for all intents and purposes invisible, so take a break and go use your computer the way you normally would to see how it feels.
If for some reason you wanted to bring them back without a reboot, the same command with an -e
instead of a -d
will do the trick:
# Enable cores 12 and 13.
sudo chcpu -e 12,13 # CHANGEME!
Re-rerunning lscpu --extended
will confirm they have returned:
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ
…
12 0 0 10 64:64:8 yes 2100.0000
13 0 0 11 66:66:8 yes 2100.0000
Persist the Changes
There isn't a configuration file or anything for this; to persist the changes, chcpu
just needs to be rerun during system startup.
For our purposes, a simple systemd script will do the trick, but there are a million alternatives so feel free to follow your heart.
If you're following me instead, just save this snippet to /usr/lib/systemd/system/disable-e-cores.service
, making sure to change the core numbers to match your own.
[Unit]
Description=Disable E-Cores
[Service]
Type=oneshot
ExecStart=/usr/sbin/chcpu -d 12,13
[Install]
WantedBy=multi-user.target
Enable the service and reboot:
# Make sure systemd knows about the new service.
sudo systemctl daemon-reload
# Enable it.
sudo systemctl enable disable-e-cores.service
# Reboot.
reboot
Once you're back, you can verify it worked by running:
sudo systemctl status disable-e-cores.service
---
1. Apparently 16GiB
of RAM is not enough to stream rugbypass.tv videos in Firefox while waiting for an LTO-optimized Linux kernel to finish building in a docker container.
2. Intel markets the best cores as being for "performance" and the worst cores as being for "efficiency", so they're often abbreviated as P- and E-cores respectively. They don't seem to talk about the mid-range majority at all…
3. When benchmarking code changes, I find it helpful to temporarily disable the mid-range cores too. This makes the benchmarks take longer, but because the remaining cores all have the same clock speed, the timings are a lot more consistent.