Measuring Your Application Power and Carbon Impact (Part 1)
The first step in minimizing the carbon impact of an application is understanding what the impact is. In this post I’m going to walk through the steps to measure the total power consumed by your application using the built in Windows Energy Estimation Engine (E3). This is the first in a series of posts about measuring energy and carbon impact of Windows client applications. My colleague Sara will be following up next with a higher level post about how to more generally think about client and service power consumption.
Today the E3 measurement capability is subject to one important constraint: it needs to be executed on a device which contains a battery. To get a sense of the type of data which you can view first open an admin command prompt and type powercfg.exe /srumutil
If you ran this correctly you should get exit code 0.
By default this will dump a csv file to the directory where you executed it from called srumutil.csv. The file in its default first run state is going to dump the last 7 days of application energy data pivoted by hardware component E3 is attributing energy use to as well as a few state variables such as OnBattery, ScreenOn, InteractivityState as well as the Time over which the data was measured. There is a a lot of data here but for our purposes let’s set it up to focus in on an application we are developing.
Resetting the Local Db
To do that we are going to backup then clear out the local db where the service is storing the data we just dumped. Running these three commands will stop the service, backup the local db containing the data, and restart the service.
Running the App
Now we can execute the application we want to generate a measurement for. For the purpose of this series of blog posts I’m going to draw on an excellent repo containing several benchmarks: https://github.com/greensoftwarelab/Energy-Languages
Just to show the most simple example possible I navigate to a single C# benchmark in that repro, updated it to .Net Core 3.1, build and run it from the command line.
At this point we can see the energy stats for our utilization by first running powercfg /srumutil again then opening the output srumutil.csv in excel and filtering to our application. For ease of viewing I pivoted the filtered data here.
We can see that this process only really affected the CPU energy (measured in milli-Joules here). As we continue this series we’ll get in to more advanced scenarios. There are a couple of caveats to note at this point. The data provided are estimates and don’t necessarily reflect the energy at the wall (key things missing will be loss from the AC adapter, fans, discreet GPU utilization and a few other items).
We’ll that test was a good representative scenario, which resulted in 410 mJ used, for our average user for a single execution of our application. To estimate the Carbon impact of this application we need a few things such as how often this scenario is run, by how many users, what locale those users are in, and whether the hardware configurations of those users are likely representative of our test value (if they aren’t you will want to generate a distribution of values based on different hardware configs which represent your user base–we’ll try and cover how one might estimate this in another future post). For simplicity sake let’s assume the Surface Pro 2017 I just used is representative of the average user. Also assume there are 1 million users exclusively in the US who run the application on average 10 times per day.
Collectively those users are using 410 mJ * 1,000,000 * 10 = 4,100,000,000 mJ per day.
Conversion to CO2
The last step is to convert this value to CO2 equivalents. Since the energy to CO2 relationship is entirely dependent on the energy generation source we will use the average value for the US (for this conversion I’m going to use the value of .475 mtCO2e per MWhr but it varies widely per country so the more you can do this conversion per country or region the more accurate your data will be).
First convert mJ to MWHr (1 mJ = 2.8×10^-13 MWHr) then use the factor to convert to mtCO2e:
4.1×10^9mJ * 2.8×10^-13 MWHr/mJ * .475 mtCO2e/MWHr = 5.4×10^-4 mtCO2e
Now that’s not a huge impact but this was a very small application on a very small user base; it is equivalent to an average car driving about 1.4 miles . Collectively across the billions of computers in the world this quickly adds up to be a significant opportunity for reductions. Converting in to CO2 isn’t strictly necessary in this example but becomes more important if you are running globally distributed applications and services as the grid mix in certain locals can inadvertently help or hinder your efforts.
: https://www.epa.gov/energy/greenhouse-gas-equivalencies-calculator Additional references
: Docs for srumutil: https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/powercfg-command-line-options#option_srumutil
: All powercfg options: https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/powercfg-command-line-options
: Generating Battery Report: https://www.tenforums.com/tutorials/63430-generate-battery-energy-estimation-report-windows-10-a.html
: Webcast for E3 tooling: https://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-157-Energy-Estimation-Engine-E3
Thank you very much for this informations.
Is there also an API for “powercfg /srumutil” to get the energy consumption within another (ex. .NET) application directly, without calling powercfg and parsing the file?
Hi Christoph, today there isn’t an API to get this information. It is something we are considering for a future update. If you would like to log a feature suggestion in Feedback Hub that would help connect your ask with our internal feature tracking. Thanks!
Great Article ! Thanks Scott
Thanks for the post! I’m trying to run powercfg.exe /srumutil on my Surface Laptop 3, but I get an error saying “A device attached to the system is not functioning.” Any ideas on troubleshooting this?
My guess is that you need to launch your command prompt as administrator. That is the same error I get when I don’t use an elevated command prompt. Let me know if that works for you.