Linux 5.8 Brings Per-Core Energy Sensor Support For AMD CPUs

From LinuxReviews
Jump to navigationJump to search
Amdlogo.png

The new amd_energy can in theory tell you how much energy each core on AMD family 17h and above CPUs consume as well as the total amount of energy consumed by the CPU package. The readings given in Joules and the reported total package figures appear to be fairly accurate. If the per-core energy readings are correct or not is an entirely different question.

written by 林慧 (Wai Lin). published 2020-07-09last edited 2020-08-04

Kemonomimi rabbit.svg
Updated: Kernel 5.8 is now released and it turns out this article is inaccurate. The energy readings from some AMD CPUs wre found to be inaccurate. AMD developer Naveen Krishna Chatradhi therefore changed the amd_energy driver included in the Linux 5.8 final release so it only works with on one safe/accurate family of AMD processors:
 static const struct x86_cpu_id cpu_ids[] __initconst = {
	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x17, 0x31, NULL),
 	{}
 };
 MODULE_DEVICE_TABLE(x86cpu, cpu_ids);

The amd_energy driver in Linux 5.8 does NOT work on first and second generation Ryzen processors. It did during the release candidate cycle but it does not work on anything other than family 17 subfamily 31 processors in the final 5.8 release.

Amd energy.jpg
Enabling CONFIG_SENSORS_AMD_ENERGY gives you some kind of readings in Joules that may or may not accurately reflect the CPUs energy consumption.

Kernel 5.8 has a fancy new feature called CONFIG_SENSORS_AMD_ENERGY. Enabling this makes the kernel produce some values in Jules that may or may not reflect total energy consumption. The values do appear to be close to accurate.

The kernel help story for CONFIG_SENSORS_AMD_ENERGY is:

"If you say yes here you get support for core and package energy sensors, based on RAPL MSR for AMD family 17h and above CPUs.

This driver can also be built as a module. If so, the module will be called as amd_energy."

CONFIG_SENSORS_AMD_ENERGY documentation

Testing the amd_energy module on a Ryzen 1600X and a Ryzen 2600 using Linux 5.8 rc4 (git g0bddd227f3dc) shows values that were increasing continuously, more so under load. The amd_energy module appear to record the total power consumed since boot in Joules.

Ryzen 1600X Ryzen 2600
idle, boot 30m uptime 1d uptime idle, boot 1h uptime
Ecore000 189.40 J 4.36 kJ 166.19 kJ 250.17 J 4.15 kJ
Ecore001 124.56 J 4.19 kJ 161.38 kJ 155.64 J 4.14 kJ
Ecore002 100.68 J 4.23 kJ 168.33 kJ 155.29 J 4.14 kJ
Ecore003 108.01 J 4.42 kJ 177.08 kJ 122.64 J 4.03 kJ
Ecore004 79.36 J 4.36 kJ 177.08 kJ 103.17 J 4.01 kJ
Ecore005 102.96 J 4.30 kJ 174.14 kJ 108.33 J 4.00 kJ
Esocket0 2.26 kJ 65.80 kJ 3.20 MJ 9.89 kJ 80.02 kJ

The power P in watts (W) is equal to the energy E in joules (J), divided by the time period t in seconds (s): P(W) = E(J) / t(s)

Using the Ryzen 2600 figure we get 80020 J divided by (60 (seconds) * 60 (minutes)) = 22 W

The power P in kilowatts (kW) is equal to the power P in watts (W) divided by 1000: P(kW) = P(W) / 1000

22 W / 1000 = 0.022 kW.

The energy E in kilowatt-hour (kWh) is equal to the power P in kilowatts (kW), times the time t in hours (h): E(kWh) = P(kW) * t(h)

That means that the mostly idle Ryzen 2600 consumed 0.022 kW/h according the reported values and these calculations. That's 0.528 kW/h per day.

In the case of a Ryzen 1600X used for all kinds of things, including occasional compiling, after 24 hours: 3.20 MJ = 3200000J and there is 60 seconds * 60 minutes * 24 hours = 86400 seconds in a day which works out to 37W or 0.037 kW. That *24 equals 0.888 kW/h power consumed by the CPU in a day.

These figure does appear to be close to accurate. They do, of course, not reflect the total system power consumption as the amd_energy module only measures the energy consumed by the CPU socket.

For comparison: A cheap at the wall power meter reports a 80 W total system power consumption on the Ryzen 2600 machine when that machine is mostly idle (not including the monitors and the surround receiver). The rest of the components in that machine would, if the CPU package measurement by amd_energy is correct, consume 80W-22W=58W.

It is interesting to note that the Esocket0 value does not equal the sum of Ecore00[0-5]. Take the 30 minute uptime figures for the Ryzen 1600X above as an example: The sum of the reported figures for all cores is 25.86 kJ. That is less than half of the reported 65.8 kJ Esocket0 value. Where oh where did the rest of the energy going to the socket go? Who knows.

Regardless of what you think of the accuracy of these figures: The code for the amd_energy module is merged. It will be available when Linux 5.8 is released later this summer.


5.00
(one vote)

avatar

Anonymous user #1

2 months ago
Score 0++

> Where oh where did the rest of the energy going to the socket go? Who knows.

Aside from CPU cores, there's also a huge IO die which manages PCI-E, RAM, etc.
avatar

Anonymous user #1

2 months ago
Score 0++

> X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x17, 0x31, NULL),

That means AMD Family 23 Model 49 CPUs, i.e. AMD EPYC.
avatar

Anonymous user #1

2 months ago
Score 0++

> The values do appear to be close to accurate.

I'm not sure you can call the values accurate unless you measure the CPU power consumption directly ;-) Since the patch disabled most Zen based CPUs and left only EPIC, it's not obvious whether it reports correct values for unsupported CPUs.

// b.
Add your comment
LinuxReviews welcomes all comments. If you do not want to be anonymous, register or log in. It is free.