# TDP and Turbo Parameter Modification with MSR on Non-Overclockable CPUs ## Disclaimer - Modifying MSR may void your CPU's (or system board's) warranty. Proceed with caution. I am not responsible for any damage caused by this article. - MSR addresses vary significantly between CPUs. Check your CPU's MSR address using [Intel's documentation](https://software.intel.com/en-us/articles/intel-sdm?wapkw=software+developer). - This has only been tested on the Intel i7-8550U (Kaby Lake R). - This article is a translation of [this article](https://blog.minori.moe/?p=989). If you can read Korean, I recommend reading that article instead. ## Introduction On Windows, [Intel XTU](https://downloadcenter.intel.com/download/24075/Intel-Extreme-Tuning-Utility-Intel-XTU-) can be used to modify turbo boost parameters and TDP-related settings. However, on other operating systems, there are no specific user-friendly tools available. In this article, I will directly modify *MSR* (Model-Specific Registers) to achieve a similar effect. ## Understanding Your CPU There are many CPU models, which we often refer to by their *friendly names*—such as "Core i7"—but this is not sufficient for this article. Some CPUs are very different even if they share the same friendly name. Conversely, some CPUs have different names but are actually variants of another CPU. Intel distinguishes between CPUs using *CPU family* and *model*. For example: ``` $ cat /proc/cpuinfo | less processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 142 model name : Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz stepping : 10 ... ``` Note that `/proc/cpuinfo` returns the CPU family and model as decimal values. ## Dependencies On Linux, you will need [*msr-tools*](https://01.org/msr-tools) and the *msr* kernel module. You may want to insert the kernel module automatically by adding the appropriate configuration (e.g., `echo msr > /etc/modules-load.d/msr.conf` in Arch Linux). You can read from MSR with `rdmsr 0x(address)` and write to MSR with `wrmsr 0x(address) 0x(value)`. When reading, you can specify bitmasks with `-f 15:0` (from bit 0 to bit 15, in reverse). ## Power/Energy/Time Units My CPU has `MSR_RAPL_POWER_UNIT` at address `606h`. ``` 606H MSR_RAPL_POWER_UNIT (RO) 3:0 = Power unit (W) = 1/2^(decimal)W - def: 0.125W 12:8 = Energy unit (J) = 1/2^(decimal)J - def: 0.00006103515625J 19:16 = Time unit (sec) = 1/2^(decimal)sec - def: 0.0009765625sec ``` These units are needed to modify existing values. ## Package Power Limits Now the fun begins: `MSR_PKG_POWER_LIMIT` contains package power limit variables. ``` 610H MSR_PKG_POWER_LIMIT (RW) 14:0 = Pkg power limit = Powerunit * decimal 15:15 = Pkg power enabled (bool) 16:16 = Pkg clamping limit (bool) 23:17 = Pkg power limit time window = 2^(21:17 bit) * (1.0 + (23:22 bit)/4.0 ) * Timeunit 46:32 = Pkg power limit 2 = Powerunit * decimal 47:47 = Pkg power 2 enabled (bool) 48:48 = Pkg clamping limit 2 (bool) 55:49 = Pkg power limit time window = 2^(53:49 bit) * (1.0 + (55:54 bit)/4.0 ) * Timeunit 63:63 = MSR lock (bool) ``` If bit 63 is 0, these values can be changed by writing to the `0x610` register. You may change the package power limit to a higher TDP and prolong the limit time window to increase your processor's performance (if not limited by thermal throttling). ## Turbo Boost Ratio Limit If `MSR_PLATFORM_INFO[28]` is 1, you can also change the turbo boost limit variable. ``` CEH MSR_PLATFORM_INFO 15:8 = Maximum non-turbo (RO) bool 28 = Programmable ratio limit for turbo (RO) bool 29 = Programmable TDP limit for turbo (RO) bool 30 = Programmable TJ offset (RO) bool 1ADH MSR_TURBO_RATIO_LIMIT (RO if MSR_PLATFORM_INFO[28]=0, else RW) 7:0 = Ratio 1C 15:8 = Ratio 2C 23:16 = Ratio 3C 31:24 = Ratio 4C ``` ## Real-life Example: Tuning the i7-8550U Processor Using the above information, I modified the MSR on my i7-8550U processor. Since this processor is limited to a 37 boost ratio when all 4 cores are being used, I changed the limitation to 40. Additionally, I changed the 23W limit to 25W with a longer (1,073,741,824 seconds) boost duration. From: ``` 610H 42819800dd80b8h 00000000 01000010 10000001 10011000 00000000 11011101 10000000 10111000 14:0 = Pkg power limit = 10111000b (184d, b8h) = 23 15:15 = Pkg power enabled (bool) = 1b 16:16 = Pkg clamping limit (bool) = 1b 23:17 = Pkg power limit time window = 11b(3d) 01110b(14d) = 2^14*(1+3/4)*(1/2)^10=28 46:32 = Pkg power limit 2 = 110011000b (408d, 198h) = 51 47:47 = Pkg power 2 enabled (bool) = 1b 48:48 = Pkg clamping limit 2 (bool) = 0b 55:49 = Pkg power limit time window = 01b(1d) 00001b(1d) = 2^1*(1+1/4)*(1/2)^10=0.00244140625 63:63 = MSR lock (bool) = 0b 1ADH 25252828h 7:0 = Ratio 1C = 40 15:8 = Ratio 2C = 40 23:16 = Ratio 3C = 37 31:24 = Ratio 4C = 37 ``` To: ``` 610H 42819800FC80C8h 00000000 01000010 10000001 10011000 00000000 11111100 10000000 11001000 14:0 = Pkg power limit = 11001000b (200d, c8h) = 25 15:15 = Pkg power enabled (bool) = 1b 16:16 = Pkg clamping limit (bool) = 0b 23:17 = Pkg power limit time window = 11b(3d) 11110b(30d) = 2^30*(1+3/4)*(1/2)^10=1073741824 46:32 = Pkg power limit 2 = 110011000b (408d, 198h) = 51 47:47 = Pkg power 2 enabled (bool) = 1b 48:48 = Pkg clamping limit 2 (bool) = 0b 55:49 = Pkg power limit time window = 01b(1d) 00001b(1d) = 2^1*(1+1/4)*(1/2)^10=0.00244140625 63:63 = MSR lock (bool) = 0b 1ADH 28282828h 7:0 = Ratio 1C = 40 15:8 = Ratio 2C = 40 23:16 = Ratio 3C = 40 31:24 = Ratio 4C = 40 ``` ## Results [turbostat](https://github.com/torvalds/linux/blob/master/tools/power/x86/turbostat/turbostat.c) reported the updated TDP limit and duration, as well as the changed turbo boost ratio. I could not test real-life performance differences, as my processor is heavily throttled by thermal throttling even at a 15W TDP.