Software Efficiency and Energy Consumption

Mirko Stocker
Growing Green Software
9 min readJun 8, 2024

--

Efficiency, in general, has long been a key concern in software development. In the early days of computing, when memory and processing power were scarce, programmers were forced to write efficient code that got the most out of the hardware. With today's abundant cheap memory, storage, and processing power and a shortage of skilled developers, hardware efficiency is often a secondary concern. Developer efficiency, which leads to increased business value, is a higher priority when choosing programming languages or frameworks. Massive computing power is only a few clicks away, thanks to the cloud. However, the move to the cloud has the potential to make software efficiency more important again. Cloud costs are directly related to resource usage and can even be reported to the users or developers on the level of individual applications or managed services used within applications.

In the realm of green software development, understanding software efficiency and energy consumption is crucial because there is a strong correlation between the two. And just like healthy plants thrive in the right conditions, efficient code runs smoothly and minimizes resource footprint. The more efficient a software system is, the less energy it consumes and the better for the environment it is. But how much energy does software consume? I was relieved to find a study that shows that I'm not the only one having a hard time answering that: A group around Candy Pang from the University of Alberta studied the knowledge of programmers about energy consumption and found that they "had limited knowledge of energy efficiency, lacked knowledge of the best practices to reduce software energy consumption, and were often unsure about how software consumes energy." Their research was peer-reviewed and published in the IEEE Software magazine. Unfortunately, the final article is behind a paywall, but the authors published a pre-print version that can be freely accessed.

This post delves into the fundamentals of energy measurement, providing software engineers with a basic understanding of energy units, energy consumption, and some energy measurement tools.

Software Efficiency

The Cambridge Dictionary offers several definitions of efficiency. In the context of computers, the following is probably the most tangible:

the relationship between the amount of energy put into a machine or process and the amount of useful work it produces.

For example, the amount of light produced by a light bulb is the useful work, and the energy consumed is the energy that the light bulb draws from the power socket. Energy labels with an easy-to-compare scale are shown on appliances such as refrigerators, washing machines, or light bulbs (at least until LED became the standard, which is way more efficient and longer-lasting than incandescent lighting).

When applied to software, efficiency is the amount of useful work a software system produces per unit of energy consumed. For example, the amount of data a web server sends to a client is the useful work, and the energy consumed is the energy the server draws. In this case, the energy consumption is not directly visible to the user but is still there. One can, of course, argue that "data transferred" does not necessarily equal "useful work." After all, the data might never be used. Still, as there is no standard definition of "useful work" in software, this will have to suffice for now.¹ Measuring software efficiency can nevertheless be helpful, for example, to compare different approaches, architectures, or products.

Another way to look at software efficiency is from a software quality perspective. The ISO/IEC 25010 Product Quality Model lists performance efficiency as one of nine characteristics as "the degree to which a product performs its functions within specified time and throughput parameters and is efficient in the use of resources." It has three sub-characteristics: Time Behavior (how well the product meets response time and throughput requirements), Resource Utilization (how well the product meets resource usage requirements), and Capacity (how well the product meets the maximum limits of a system parameter). The arc42 Quality Model lists dozens of examples of related quality requirements.

Energy Consumption

Let's take a look at the other ingredient for efficiency: energy consumption, the amount of energy a system consumes over time. Energy can be expressed in different units, such as Joules or Kilowatt-hours (or calories, but that might be more interesting for the software developers than for the software itself 😉).

1 kilowatt-hour = 1 kWh = 3600 kilojoules = 3.6 MJ

One way to measure energy consumption is by using a Wattage and current meter, which measures the power consumption of an electrical device in Watts. The power consumption is then multiplied by the time the device is used to calculate the energy consumption in Watt-hours or Kilowatt-hours. Here's an example of measuring the power consumption of the laptop I'm using to write this post:

Figure 1: A Watt-meter measuring the power consumption of my laptop.

As we can see, when I took the picture, the laptop drew about 12 Watts from the power socket. There isn't much going on my system. Spotify is playing in the background, and I'm writing this post in Visual Studio Code. If I were to use it for one hour just like this, it would consume 12 Watt-hours (or 0.012 Kilowatt-hours). Refreshing a page in the browser causes the consumption to spike to about 20 watts and then drop back to 12 (the power meter refreshes roughly once a second). Using a CPU stress testing tool, I can get the consumption up to 50-60 watts. When plugging in my external screen, usage jumps another 30 watts, which seems about right compared with the energystar label of the screen (yet another known use of an energy label).²

Such meters can give us a first impression, albeit crude, of energy consumption. But what about devices, let's say a mobile phone, that runs on battery? There are ways to measure energy consumption under such circumstances; for example, see the tutorial How to measure energy consumption with Monsoon by Luís Cruz and Rui Abreu. But it's not as easy anymore as plugging in a Watt-meter. But even with a Watt-meter, I'd still need to isolate the usage of my software that I want to measure from everything else that is going on in the system, and we also must correlate the measurements with the running time of the software. This is where energy profiling tools come into play.

Energy Profiling

Rather than treating the system as a black box, energy profiling tools measure the energy consumption from within. They are usually integrated into or use APIs of the operating system and can report energy consumption by process. Unfortunately, many of these tools work only on specific CPUs and/or operating systems. Also, not all components of a system are measured. For example, disks or peripheral devices are not. RAPL (Running Average Power Limit) is such an API for Intel-based systems to measure the energy consumption of CPUs, GPUs, and memory, which different tools can use. One commonly used tool is the Intel® Performance Counter Monitor open-source tool, which unsurprisingly doesn't work on my Apple Silicon CPU. While there seem to be tools under development that ought to support Apple Silicon (for example, PinPoint and socpowerbud), I haven't found one that works on my machine — pointers are welcome.

You might wonder, what about the overhead of profiling? Generally speaking, there are several ways to do profiling. One approach is to instrument the binary or the code to include additional instructions that record measurements. For example, let's say you want to find out how often each function in your program is called. A profiler could add "counting" instructions at the beginning of each function. Unsurprisingly, this would add quite a lot of overhead. A less invasive approach is performance counters, special-purpose CPU registers that provide information about the system. This is what RAPL uses, so the added overhead should be minimal. Of course, others have asked this question as well. Kashif Nizam Khan and a group of researchers from Finland, Switzerland, and China described several experiments in their publication RAPL in Action: Experiences in Using RAPL for Power Measurements. They conclude that “the performance overhead of RAPL measurements is considerably low and negligible.” The paper also provides a great introduction to how RAPL works.

Example

Since I haven't found a profiler that works on Apple Silicon, let's switch to a different system with more traditional hardware and operating system (Intel i7 Thinkpad running Arch Linux). The PinPoint command-line tool mentioned above, which uses RAPL under the hood, also runs on Linux and allows us to measure the energy consumption of a process. Let's measure the compilation and packaging of a Java web application:³

sudo  ~/pinpoint/build/pinpoint -r 4 -i 250 -- mvn --offline clean verify
[INFO] Scanning for projects...
...
[INFO] ------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------
[INFO] Total time: 5.377 s
[INFO] Finished at: 2024-01-04T16:39:28+01:00
[INFO] ------------------------------------------------------------------
Energy counter stats for 'mvn -o clean verify':
[interval: 250ms, before: 0ms, after: 0ms, delay: 0ms, runs: 4]

14.13 J rapl:ram ( +- 0.83% )
145.50 J rapl:cores ( +- 1.64% )
2.17 J rapl:psys ( +- 1.84% )
0.92 J rapl:gpu ( +- 5.64% )
158.42 J rapl:pkg ( +- 1.52% )

6.26829439 seconds time elapsed ( +- 2.66% )

As we can see, the process took 6.27 seconds and consumed about 175 Joules (J) of energy in total. Note that the "rapl:pkg" represents the whole CPU package and already includes the "rapl:cores" measurement, so we have to skip that entry when summing up the measurements. This is roughly as much energy as it takes to heat 1 milliliter of water by 40 degrees. RAPL was introduced for processor performance and thermal management, so it doesn't measure the energy consumption of other components, such as the disk. The network transfer is not measured either; we ran Maven offline, so this was not an issue in this example.

What do these numbers tell us? I'll admit that these are still very abstract and hard to act on from a software engineering perspective. But one thing we can do now is compare different runs of the same program over time. In a future post, we will try to integrate these numbers into a CI/CD pipeline to compare different versions of the same software to observe how energy consumption changes over time.

Another application would be to compare different but compatible runtimes. For example, we could compare the energy consumption of a Java application running on OpenJDK HotSpot with the same application running on Eclipse OpenJ9 or using ahead-of-time compiled GraalVM Native Image. Fortunately, Ionut Balosin already did this and wrote a great article on this topic: Analyzing JVM Energy Consumption for JDK 17: An Empirical Study. He measured seven JVM distributions using different applications and found significant differences between JVMs. The code for his experiments is available on GitHub.

Conclusion

This post looked at the basics of measuring software efficiency and energy consumption. We learned that:

Efficiency is the amount of useful work a software system produces per unit of energy consumed.

We also learned that:

Energy consumption can be measured in different units, such as Joules or Kilowatt-hours.

We saw that:

Energy profiling tools can help us measure the energy consumption of a process, but they are not always easy to use and don't measure all system components.

However, they give us a first impression of the energy consumption, which will help us approximate our software's energy-related emissions.

What we haven't solved yet is how we could determine if the software actually performs "useful work". One approach might be to attribute energy consumption to specific User Stories or Use Cases or even break it down to individual API calls.

Further Reading

For a more comprehensive list of energy profiling tools, see the Tools to Measure Software Energy Consumption from your Computer post by Luís Cruz.

Firefox has a great article with background information on power profiling that explains the different components of a processor (like the RAPL package mentioned above) and which tools can be used to measure them.

Another interesting tool for JVM-based applications is JoularJX by Adel Noureddine, "a Java-based agent for power monitoring at the source code level with support for modern Java versions and multi-OS to monitor power consumption of hardware and software." It can report the energy consumption of individual methods, which is very useful for optimizing code and finding hotspots. We will cover it in a future post.

Figure 2: Overview of topics that we covered in this post.
  1. There are efforts going in that direction. In Germany, the well-known environmental label Blauer Engel (blue angel) of the Federal Ministry for the Environment offers an "environmental label for resource and energy-efficient software products." We will cover this in a future post.
  2. 0.040 Kilowatt-hours multiplied by my current electricity price of 0.44 CHF/Kilowatt-hour equals 0.0176 CHF. That's about 2 USD cents per hour. Not much, but it adds up over time with many devices.
  3. The project used is Lakeside Mutual, a Spring Boot sample application we developed to demonstrate (microservice) API patterns.

--

--

Mirko Stocker
Growing Green Software

SE Prof (Cloud, Web, Programming Languages) @ OST; Partner @ Institute for Software; Co-Founder @ LegalGo