Energieverbrauch von Software: Eine Anleitung zum Selbermessen

Informations- und Kommunikationstechnik besteht aus Hardware und Software. Damit diese ressourcenschonend und emissionsarm eingesetzt werden kann, gehört zwingend dazu, den Stromverbrauch von Software unter die Lupe zu nehmen neben den Geräten wie PCs, Monitoren und Server. Durch die Art der Programmierung ist es möglich, im Softwareeinsatz Energie zu sparen. Wie man den Stromverbrauch von Software misst und deren Treibhausgasemissionen berechnet, erklärt Senior Researcher Jens Gröger hier im Blog.

Geräte wie Smartphones, Computer, Server und andere Rechenzentrumshardware werden dazu betrieben, um damit Dienste wie Datenverarbeitung, Datenspeicherung und Datenübertragung anzubieten. Diese Dienste basieren auf Software. Der Energieverbrauch von Hardware lässt sich deshalb immer auch der Software zuordnen, die darauf betrieben wird. Das Messen des Stromverbrauchs von Software ist dabei kein Hexenwerk. Mit wenigen Hausmitteln können die Leser*innen dieses Blogs den Zusammenhang von Software und Energieverbrauch selbst nachvollziehen und am eigenen Rechner überprüfen.

Maximale Leistungsaufnahme des Computers messen

Der Stromverbrauch von Computern hängt von der Komplexität der Software ab: von der Dauer der Programmausführung und der in Anspruch genommenen Rechenleistung ab. Belastet man einen Linux-Computer beispielsweise im Terminal-Fenster mit dem Befehl

$ stress --cpu 1 --timeout 60s

so wird 1 CPU-Kern 60 Sekunden lang vollständig mit Rechenoperationen ausgelastet (ein vergleichbares Programm unter MS-Betriebssystemen heißt CpuStres).
Je mehr Kerne beansprucht werden, desto höher ist die Leistungsaufnahme des Computers. Mit der ersten Messreihe wird daher die maximale Leistungsaufnahme des Computers bestimmt. Die Anzahl der belasteten CPU-Kerne wird so lange erhöht bis alle voll ausgelastet sind. Mit einem Haushalts-Energiemessgerät misst man am Computer-Stromkabel, wie die Leistungsaufnahme steigt, bis sie stagniert. (Hinweis: Diese Messung funktioniert bei batteriebetriebenen Notebooks nur dann, wenn vorher der Akku entnommen wurde und das Gerät nur über das Netzteil betrieben wird. Wer kein Messgerät hat, kann sich als erste Näherung auch am Typenschild des Netzteils orientieren und dort die Nennleistung [Watt] als maximale Leistungsaufnahme ablesen.)

Leistungsaufnahme PCs, Quelle: Öko-Institut

In der Abbildung oben habe ich diese Messung bei einem energiesparenden Mini-Computer nachvollzogen. Im Leerlaufmodus verbraucht dieser 4,4 Watt und bei der Auslastung von 4 Kernen 11 Watt. Sobald der Linux-Befehl stress versucht, mehr als die vorhandene Anzahl von 4 Kernen zu nutzen, steigt die Leistungsaufnahme nicht weiter an. Stattdessen werden die verschiedenen gestarteten Prozesse auf die vorhanden CPU-Kerne verteilt.

Bei dem hier dargestellten Computer liegt die maximale Leistungsaufnahme daher bei 11 Watt und die Anzahl der CPU-Kerne bei 4. Diese beiden Zahlen merken wir uns.

Wie mehrere Softwareanwendungen die begrenzte Zahl an CPU-Kernen nutzen

Eine CPU (Central Processing Unit) hat mindestens 1 CPU-Kern. Diesen Kern kann man sich wie einen Rechenautomaten vorstellen, der Befehle entgegennimmt, verarbeitet und schließlich wieder ein Ergebnis ausgibt. Der CPU-Kern kann dabei gleichzeitig immer nur ein einzelnes Programm abarbeiten, denn sonst würden die Rechenoperationen durcheinandergeraten.

Tatsächlich laufen auf einem Computer aber sehr viele Programme scheinbar gleichzeitig ab (wie der Blick in den Task-Manager von MS-Betriebssystemen verrät). Dies ermöglicht das Betriebssystem entweder dadurch, dass es die verschiedenen Prozesse auf verschiedene CPU-Kerne verteilt, also parallel abarbeitet. In der Regel aber auch dadurch, dass die CPU verschiedene Prozesse zeitlich hintereinander verschachtelt ausführt. Mehrere Rechenprozesse können sich so die Rechenleistung eines CPU-Kerns aufteilen, indem jeder Prozess ein paar Millisekunden Rechenzeit zugeordnet bekommt, bevor der nächste Prozess aus der Warteschlange geholt wird und den Kern nutzen darf. Je mehr Prozesse gleichzeitig laufen, desto länger benötigt die CPU daher, bis sie alle Prozesse häppchenweise abgearbeitet hat.

Warum die CPU-Kerne für den Energieverbrauch der Software relevant sind

Mit dem Verständnis, dass Software immer komplette CPU-Kerne beansprucht, dies aber zeitlich gestaffelt tut, kann der Energieverbrauch der Software nun der Prozesslaufzeit zugeordnet werden. Dabei ist die echte Laufzeit des Programms, also die verstrichene Zeit vom Starten bis zum Beenden, nachrangig. Was zählt, ist die während der Laufzeit in Anspruch genommene CPU-Zeit. Ein Programm, das eine Sekunden lang die gesamte CPU beansprucht, benötigt genauso viel Energie, wie eins, das über 10 Sekunden hinweg immer nur 10 Prozent der CPU-Zeit beansprucht.

Wird ein Prozess gestartet, so vergibt das Betriebssystem dem Prozess eine eindeutige Prozess-Identifikationsnummer (PID). Das Betriebssystem führt eine Statistik, wie viel CPU-Zeit der Prozess bisher benötigt hat (TIME) und merkt sich den aufrufenden Befehl, also den Namen des Programms (CMD).

Unter Linux kann man diese Statistik beispielsweise mit dem Befehl ps -e auslesen:

$ ps -e
  PID TTY          TIME CMD
    1 ?        00:16:27 systemd
    2 ?        00:00:00 kthreadd/150088
    3 ?        00:00:01 khelper
  124 ?        00:01:55 systemd-logind
  128 ?        00:04:15 dbus-daemon
  361 ?        00:00:00 agetty
  362 ?        00:00:00 agetty
  443 ?        00:00:14 xinetd
 1578 ?        00:00:05 named
 2805 ?        01:02:12 mysqld
...

Diese Statistik machen wir uns zur Berechnung des Stromverbrauchs zunutze.

Der Software auf den Zahn fühlen: Die Betriebssystem-Statistik auswerten

Alles was wir nun noch tun müssen, um den Stromverbrauch von Software zu erfassen, ist die Betriebssystem-Statistik auszuwerten. Dabei kann es vorkommen, dass eine einzelne Softwareanwendung mehrere Prozesse gleichzeitig startet und dadurch mehrere CPU-Kerne oder mehrere Zeitfenster der CPU beansprucht. Da sich die Statistik auch den Namen des aufrufenden Programms merkt (CMD), müssen wir sie nicht nach Prozess-IDs filtern, sondern nach Programmnamen.

Hierzu habe ich kleines Python-Skript geschrieben, das ich unter https://github.com/oekoj/softwarefootprint zur freien Verfügung und zum weiteren Experimentieren abgelegt habe. Das Programm läuft auf allen Betriebssystemen, auf denen auch ein Python-Interpreter und die Python-Bibliothek psutil installierbar sind: also neben Linux auch auf Windows und macOs.

Das Skript mit dem Namen softwarefootprint.py durchsucht die Prozess-Statistik des Betriebssystems nach dem Auftauchen eines vorgegebenen Programmnamens und zählt die von den verschiedenen Prozessen benötigten CPU-Zeiten zusammen.

In der nachfolgenden Abbildung wird dies für das Programm lasttreiber exemplarisch dargestellt:

python softwarefootprint.py lasttreiber

waiting for 'lasttreiber' to appear in process list
waiting for 'lasttreiber' to appear in process list
waiting for 'lasttreiber' to appear in process list

----------------------------------------------------------
time    timestamp         %CPU   CPUTIME   PIDs
0.00    1653584307.88     0.00      0.37   1953
1.06    1653584308.94    99.00      1.42   1953
2.12    1653584310.00   100.90      2.49   1953
3.18    1653584311.06   100.00      3.55   1953
4.24    1653584312.12   100.00      4.61   1953
...
12.72   1653584320.60   100.00     13.08   1953
13.78   1653584321.66   100.00     14.14   1953
14.84   1653584322.72   100.00     15.20   1953
15.90   1653584323.79    34.70     15.57   1953
16.97   1653584324.86     0.00     15.57   
----------------------------------------------------------

Mit dem Starten des Python-Skripts softwarefootprint.py mit dem übergebenen Programmnamen lasttreiber wartet das Skript auf das Auftauchen des Namens in der Prozess-Statistik. Das Programm lasttreiber muss nun in einem zweiten Terminal-Fenster oder durch Doppelklick auf einer grafischen Benutzeroberfläche gestartet werden. Sobald der Programmnamen in der Statistik auftaucht, gibt das Skript zirka jede Sekunde den aktuellen Stand der CPU-Zeit (CPUTIME) aus, die durch dieses Programm beansprucht wurde.

Im oben dargestellten Fall ist dem Programm nur eine einzelne Prozess-ID (PID) mit der Nummer 1953 zugeordnet. Es können aber auch mehrere sein. Bei mehreren PIDs werden die CPU-Zeiten jeweils aufaddiert. Sobald der übergebene Programmnamen nicht mehr in der Statistik auftaucht, stoppt das Logging und das Skript wird beendet. Das Programm lasttreiber im Beispiel oben hat für den kompletten Durchlauf 15,57 Sekunden CPU-Zeit benötigt.

Von der CPU-Laufzeit zum Energieverbrauch und den Treibhausgasemissionen

Was auf die Messung der CPU-Laufzeit nun folgt, ist einfaches Rechnen. Der Energieverbrauch, der der Software zugeordnet werden kann, berechnet sich als:

Energieverbrauch = CPU-Laufzeit / CPU-Kerne * maximale Leistungsaufnahme

In dem oben dargestellten Fall als:

15,57 s / 4 * 11 W = 42,8 Ws

Das Python-Skript softwarefootprint.py übernimmt diese Rechenaufgabe für uns, vorausgesetzt natürlich, wir haben die maximale Leistungsaufnahme des aktuellen Computers (11 Watt) in den Programmcode übertragen (max_power = 11). Die Anzahl der CPU-Kerne ermittelt das Programm selbst.

Loggig for Command 'lasttreiber' finished

This Computer has 4 CPUs or CPU-cores and a maximum power of 11 Watt
energyconsumption = cpuTime / cpu_number * max_power

Software Footprint of 'lasttreiber' on this Computer:
Energy Consumption: 42 Ws
Carbon emissions:   0.004 gCO2e

Neben dem Energieverbrauch berechnet uns das Python-Skript auch die mit dem Energieverbrauch der Software zusammenhängenden Treibhausgasemissionen.

Mit dem Emissionsfaktor des deutschen Strommixes von 0,311 Kilogramm CO2-Äquivalente pro Kilowattstunde Strom im Jahr 2020 (Quelle: EEA) berechnen sich die Treibhausgasemissionen einfach mit der Formel:

Treibhausgasemissionen [gCO2e] = Energieverbrauch [Ws] * 0,311 [kg/kWh] / 3600 [s/h]

Das Programm lasttreiber hat entsprechend der Darstellung oben bei der Ausführung rund 4 Milligramm CO2-Äquivalente (CO2e) verursacht.

Vergleich von Programmen

Mit dem Mitschreiben der CPU-Auslastung mithilfe des Python-Skripts softwarefootprint.py können wir jetzt verschiedene Programme und Programmvarianten miteinander zu vergleichen. Wir können beispielsweise vergleichen, welcher Programmcode zur Erfüllung derselben Aufgabe sparsamer läuft.

Ein Beispiel: Das Berechnen der Fakultät der Zahl 100000 kann man (in Python) beispielsweise durch den Befehl factorial aus der der Mathematik-Bibliothek math erledigen:

# Variante 1
import math
print (math.factorial(100000))

Oder man programmiert eine Schleife, die die Zahlen 1 bis 100000 nacheinander multipliziert:

# Variante 2
f=1
for n in range(100000):
    f=f*(n+1)
print(f)

Der Vergleich beider Varianten zeigt, dass die erste Variante mit der Mathematik-Bibliothek rund 3 Sekunden CPU-Zeit beansprucht und die zweite Variante mit der programmierten Schleife 6 Sekunden. Die Variante 2 benötigt demnach doppelt so viel Energie und verursacht die doppelten Treibhausgasemissionen.

Die Prüfung der in Anspruch genommenen CPU-Kapazitäten kann man auch routinemäßig in die Software-Entwicklung integrieren. Stehen verschiede Lösungsmöglichkeiten (z.B. verschiedene Algorithmen, verschiedene Bibliotheken oder verschiedene Variablentypen) zur Verfügung, so kann man über das Messen der CPU-Laufzeit schnell feststellen, welche davon die effizientere Variante ist.

Vergleich von Webseiten

Eine weitere Anwendungsmöglichkeit bietet das Logging-Skript, wenn man es einen definierten Zeitraum lang ausführt. Hierzu kann dem Skript als zweiter Parameter eine Zeitangabe in Sekunden übergeben werden (python softwarefootprint.py CMDNAME LOGTIME). Dann wird nicht der gesamte Energieverbrauch der Software bis zum Beenden gemessen, sondern nur der Energieverbrauch innerhalb des genannten Zeitraums. So kann man beispielsweise den Aufwand zum Starten eines Programms und dessen Energieverbrauch im Leerlaufzustand messen.

Als praktische Anwendung zeige ich das Starten des Internetbrowsers Firefox mit verschiedenen Webseiten. Über 60 Sekunden lang wird gemessen, wie viel der Browser für sein eigenes Starten und das Aufrufen der Webseite an CPU-Zeit verbraucht. Die Unterschiede zwischen der leeren Startseite (about:blank) und den einzelnen Webseiten zeigen damit den Mehrverbrauch auf, der durch die jeweiligen Webseitenaufrufe verursacht wird.

Aufruf des Logging-Skriptes:

$ python softwarefootprint.py firefox 60

Aufruf des Internetbrowsers von einem zweiten Terminal-Fenster aus (bevor der nächste Befehl gestartet wird, muss der Browser zunächst manuell beendet werden):

$ firefox about:blank
$ firefox https://oeko.de
$ firefox https://amazon.com
$ firefox https://web.de

Schreibt man die Logging-Zeilen mit und überträgt sie in ein Diagramm, so ergibt sich aus den aufgezeichneten Werten schließlich das nachfolgende Bild:

Co2-Emissionen beim Aufruf verschiedener Websiten, Quelle. Öko-Institut

Rechts habe ich an das Diagramm noch die zugehörigen Treibhausgasemissionen geschrieben. Es macht durchaus einen Unterschied, ob der Browser mit einer blanken Startseite aufgerufen wird (1,9 mg CO2e) oder mit einer sehr aufwändig gestalteten Webseite, wie dem Nachrichtenportal web.de (12,9 mg CO2e). Die hier angegeben Werte wurden auf dem hier genutzten Mini-Computer (maximale Leistungsaufnahme 11 Watt) gemessen. Beim Aufruf der Webseiten mit einem Smartphone, einem Laptop oder einem Desktop-PC werden mit Sicherheit andere CPU-Laufzeiten und Treibhausgasemissionen verursacht.

Werden komplexe Softwareanwendungen wie ein Browser untersucht, so muss man noch die Besonderheiten der jeweiligen Programme beachten. Der Browser legt beispielsweise ein Zwischenspeicher, den Cache an, in dem er bereits geladene Dateien für einen gewissen Zeitraum ablegt. Dadurch kann die Messung derselben Webseite nicht unmittelbar wiederholt werden. Zunächst muss in diesem Fall der Cache gelöscht werden.

Aufruf zum Experimentieren und Weiterentwickeln

Auf unseren Computern und Servern laufen eine Unzahl von Softwareanwendungen, die allesamt Energie und Hardwareressourcen verbrauchen. Mit dem Skript softwarefootprint.py können wir die Umwelteffekte dieser Programme offenlegen.

  • Wer hat ein Gefühl dafür, wieviel Treibhausgasemissionen der Virusscanner oder der Indexierungsdienst verursacht?
  • Wieviel der standardmäßig eingehängte Netzwerkspeicher (z.B. onedrive, dropbox)?
  • Browser und Bildbetrachter, die im Hintergrund laufen?
  • Oder scheinbar längst beendete Videokonferenzprogramme (z.B. skype, zoom, teams)?

Auch wenn es im Einzelfall nur wenige Gramm CO2-Äquivalente sind, so macht Kleinvieh auch Mist. Insbesondere dann, wenn solche Programme weit verbreitet sind und viel genutzt werden.

Ich lade die Leser*innen dazu ein mit diesem Werkzeug zu arbeiten und damit Erfahrungen zu sammeln.

  • Beispielsweise beim Vergleich von Software mit der gleichen Aufgabe,
  • beim Vergleich von Webseiten oder Videokonferenzdiensten und
  • am besten natürlich beim eigenen Programmieren und der Optimierung des eigenen Codes.
  • Wer darüber hinaus Lust hat, das Python-Skript weiterzuentwickeln, ist ebenfalls herzlich dazu eingeladen, bessere Versionen davon zu erstellen.

Das hier vorgestellte Skript bietet einen ersten und einfachen Zugang, den Energieverbrauch und die Treibhausgasemissionen von Software auf lokalen Computern abzuschätzen. Mir ist bewusst, dass durch das reine Auswerten von Logfiles der CPU-Laufzeiten andere wichtige Informationen unberücksichtigt bleiben, wie die Nutzung von Arbeitsspeicher (RAM), die Festplattenzugriffe, die Datenübertragung und Grafikprozessoren (GPU). Für die kompliziertere Messung verweise ich auf unser Forschungsprojekt, das wir durchgeführt haben.

Die hier vorgestellten Vereinfachungen haben jedoch den Charme, dass der Aufwand für das Messen und das Auswertungsskript überschaubar bleiben und noch von jeder Programmier*in nachvollzogen werden kann.

Kleiner Ausblick

Ich würde mir wünschen, dass es zukünftig ein Systemwerkzeug gibt, in dem, ähnlich dem Taskmanager, die Software-spezifischen Ressourcenverbräuche und Treibhausgasemissionen angezeigt werden. Bis es so weit ist, können wir das vorgestellte Skript dazu nutzen, um selbst Erfahrungen zu sammeln. Es kann dabei helfen, das „Mysterium um den Energieverbrauch von Software“ etwas transparenter zu machen und dazu anstoßen, Software nachhaltiger zu programmieren.

Jens Gröger ist Senior Researcher im Institutsbereich Produkte & Stoffströme im Büro Berlin und Experte für nachhaltige Informations- und Kommunikationstechnik.

Studien

Weitere Informationen

Was macht mein Computer, wenn ich nicht hinschaue?

Einfluss von Software auf den Ressourcenverbrauch (Beitrag auf der Bits & Bäume-Konferenz 2018)

Möchten Sie diesen Beitrag kommentieren?

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.