Disclaimer
I'm not responsible if you ruin your system, this guide functions as documentation for future me. While this should just cause MCEs or system resets if done wrong it might also be able to ruin things in a more permanent way.
Why do this
It lowers temps generally and if you hit thermal throttling (as happens with my 5th Generation X1 Carbon) you may thermally throttle less often or at a higher frequency.
Prework
Repaste first, it's generally easier to do and can result in better gains (and it's all about them gains). For instance, my Skull Canyon NUC was resetting itself thermally when stress testing. Repasting lowered the max temps by 20°C.
Undervolting - The How
I based my info on https://github.com/mihic/linux-intel-undervolt which seems to work on my Intel Kaby Lake based laptop.
Using the MSR registers to write the values via msr-tools wrmsr binary.
The following python3 snippet is how I got the values to write.
# for a -110mv offset I run the following
format(0xFFE00000&( (round(-110*1.024)&0xFFF) <<21), '08x')
What you are actually writing is actually as follows, with the plane index being for cpu, gpu or cache for 0, 1 or 2 respectively.
constant | plane index | constant | write/read | offset |
---|
80000 | 0 | 1 | 1 | F1E00000 |
So we end up with 0x80000011F1E00000
to write to MSR register 0x150.
Undervolting - The Integration
I made a script in /opt/bin/
, where I place my custom system scripts called undervolt.sh
(make sure it's executable).
#!/usr/bin/env sh
/usr/sbin/wrmsr 0x150 0x80000011F1E00000 # cpu core -110
/usr/sbin/wrmsr 0x150 0x80000211F1E00000 # cpu cache -110
/usr/sbin/wrmsr 0x150 0x80000111F4800000 # gpu core -90
I then made a custom systemd unit in /etc/systemd/system
called undervolt.service
with the following content.
[Unit]
Description=Undervolt Service
[Service]
ExecStart=/opt/bin/undervolt.sh
[Install]
WantedBy=multi-user.target
I then systemctl enable undervolt.service
so I'll get my settings on boot.
The following script was also placed in /usr/lib/systemd/system-sleep/undervolt.sh
to get the settings after recovering from sleep, as they are lost at that point.
#!/bin/sh
if [ "${1}" == "post" ]; then
/opt/bin/undervolt.sh
fi
That's it, everything after this point is what I went through in testing.
Testing for stability
I stress tested with mprime in stress mode for the CPU and glxmark or gputest for the GPU. I only recorded the results for the CPU, as that's what I care about.
No changes:
- 15-17W package tdp
- 15W core tdp
- 3.06-3.22 Ghz
50mv Undervolt:
- 15-16W package tdp
- 14-15W core tdp
- 3.22-3.43 Ghz
70mv undervolt:
- 15-16W package tdp
- 14W core tdp
- 3.22-3.43 Ghz
90mv undervolt:
- 15W package tdp
- 13-14W core tdp
- 3.32-3.54 Ghz
100mv undervolt:
- 15W package tdp
- 13W core tdp
- 3.42-3.67 Ghz
110mv undervolt:
- 15W package tdp
- 13W core tdp
- 3.42-3.67 Ghz
started getting gfx artifacts, switched the gfx undervolt to 100 here
115mv undervolt:
- 15W package tdp
- 13W core tdp
- 3.48-3.72 Ghz
115mv undervolt with repaste:
- 15-16W package tdp
- 14-15W core tdp
- 3.63-3.81 Ghz
120mv undervolt with repaste:
- 15-16W package tdp
- 14-15W core tdp
- 3.63-3.81 Ghz
I decided on 110mv cpu and 90mv gpu undervolt for stability, with proper ventilation I get about 3.7-3.8 Ghz out of a max of 3.9 Ghz.
Other notes: Undervolting made the cpu max speed less spiky.