TP Mesures de Consommation

Introduction

Dans cette séance, nous allons apprendre à mesurer l’énergie électrique nécessaire à l’exécution de systèmes de calculs numériques, et essayer appréhender la pollution induite par cette consommation d’énergie. Nous allons commencer par quelques rappels et des calculs concernant la puissance et l’énergie électrique.

Si vous avez bien tout suivi la première partie du module Numérique Responsable, vous savez désormais qu’en France au moins, cette consommation en phase d’usage (que nous allons mesurer aujourd’hui) n’est pas celle qui a le plus d’impact environnemental dans le numérique. Ce n’est pas non plus une raison pour ne pas en parler, ni chercher des moyens de limiter cette consommation. Et puis, c’est une bonne occasion de parler également d’énergie et d’impact carbone au sens large.

La première partie de ce TP est en grande partie adaptée d’un énoncé proposé par Kevin Marquet pour un TP du département Télécom de l’INSA Lyon.

Quelques rappels sur la puissance et l’énergie

L’énergie caractérise le service énergétique rendu (travail, éclairage, …). La calorie (4,18 J) est la quantité de chaleur nécessaire pour élever 1g d’eau de 1◦C.

La puissance est le débit d’énergie qui a lieu lors d’une conversion, \(P = \frac{dE}{dt}\) avec \(P\) la puissance en Watt (W ou kW), \(E\) l’énergie (J ou kWh) et \(t\) le temps (s ou h).

La puissance caractérise le convertisseur d’énergie et plus particulièrement sa capacité à transformer plus ou moins vite l’énergie. Ainsi un moteur électrique de 20 kW transforme une même quantité d’énergie électrique deux fois plus rapidement qu’un moteur de 10 kW, il convertit deux plus fois plus vite l’énergie électrique qu’il reçoit en énergie mécanique et effectue donc un même travail plus rapidement.

Une transformation énergétique plus rapide nécessite un convertisseur plus puissant, donc plus cher, requérant plus de matières premières et consommant donc plus d’énergie grise, celle nécessaire à sa fabrication. En outre, vouloir réaliser plus rapidement un service énergétique requiert plus d’« énergie utile », par exemple : sur un trajet de 100 km une automobile dont la résistance à l’avancement serait de 400 N à 100 km/h consommerait une énergie de 40 MJ (soit 400 100 103 J) et une puissance mécanique de 11 kW (11 kWh en 1 heure) ; ce même déplacement à 130 km/h conduirait à une résistance à l’avancement de 650 N et requerrait 65 MJ et 23,5 kW (soit 18 kWh en 0,77 h).

Question 1 : Indiquez la puissance approximative de quelques appareils électriques que vous connaissez (bouilloire, four, …).

Rappels : quelques notions physiques autour de l’électricité

Vous devez vous rappeler que \(P = U \cdot I\), et même que \(U = R \cdot I\), et peut-être aussi que \(I = \frac{dQ}{dt}\). Mais très souvent, des gens appliquent ces formules sans avoir d’intuition permettant d’appréhender la tension \(U\), l’intensité \(I\), la résistance \(R\), et \(Q\) la quantité de charge.

On peut faire une analogie entre le courant électrique à travers un circuit et un courant d’eau dans un tuyau. Dans ce cas :

  • On peut voir le flot d’électrons dans le circuit comme le flot d’eau dans un tuyau ;
  • On peut voir l’intensité I de la même manière que le débit d’eau dans le tuyau ;
  • On peut voir la tension U, aussi appelée différence de potentiel, comme la différence de hauteur entre les deux bouts du tuyau, amenant la gravité à déplacer
  • On peut voir la résistance comme un rétrécissement du tuyau.

Partie 1 : Jouons un peu avec un wattmètre

Mesures de puissance et d’énergie électrique

Il existe différents moyens de mesurer la puissance électrique consommée par un appareil. La manière la plus fiable d’évaluer la consommation de ressources informatiques est probablement d’utiliser un dispositif du type PDU (Power Distribution Unit), car la plupart des équipements de ce type sont munis de sondes permettant de mesurer la consommation de chaque prise de manière fiable et suffisamment échantillonnée pour délivrer une estimation précise de l’énergie consommée. N’ayant pas à disposition ce type d’équipement, dans ce TP, nous allons en utiliser 2 :

  • un wattmètre branché sur l’alimentation électrique de divers appareils. Nous allons utiliser dans ce TP un wattmètre Voltcraft Energy Logger 4000F (gentiment prêté par ÉcoInfo pour notre TP − on dit merci ÉcoInfo) ;
  • un ensemble de sondes logicielles permettant d’estimer la consommation électrique induite par l’exécution de certains programmes sur une machine (partie suivante du TP).

Dans cette partie du TP, nous allons nous focaliser sur un ensemble d’appareils que nous avons directement à notre disposition. L’objectif de cette partie sera essentiellement de remplir la table 1.

Table 1: Puissance et énergie électriques consommées par différents appareils.
Appareil Puissance estimée Puissance mesurée Énergie calculée à partir de la moyenne
PC fixe
Ordinateur portable, batterie en charge
Ordinateur portable, batterie chargée
Chargeur de portable seul
Écran plat
Téléphone en charge

Question 2 : Sans rien mesurer, ordonnez la liste des appareils par ordre croissant de la puissance que vous pensez nécessaire pour les faire fonctionner puis remplissez la première colonne de la table 1 avec la puissance que vous estimez nécessaire. Vous pourrez adapter la liste des appareils en fonction de ce que vous avez à disposition pendant le TP.

Question 3 : Maintenant, notez la puissance électrique consommée par les différents appareils à l’aide d’un wattmètre (remplissez la troisième colonne de la la table 1).

Question 4 : Calculez l’énergie nécessaire au fonctionnement de chaque appareil pendant 1 heure, en supposant que la puissance soit constante (remplissez la quatrième colonne de la table 1).

Question 5 : Pour certains appareils, ce n’est pas un problème de calculer l’énergie consommée en supposant la puissance constante, mais pour beaucoup d’appareils numériques, c’en est un. Par exemple, l’énergie consommée par des serveurs varie en fonction de la charge. C’est le cas également des terminaux et des écrans. Dans cette question, nous allons observer cela sur un écran. Procédez comme suit (lisez toutes les instructions ci-dessous avant de commencer).

  • Munissez-vous d’un crayon, d’une feuille de papier et d’un chronomètre.
  • Branchez le wattmètre sur la prise d’alimentation de l’écran et placez-le en mode puissance.
  • Allumez l’écran (si ce n’est pas déjà fait)
  • Laissez l’écran allumé pendant 1 minute. Pendant cette minute, notez sur votre feuille la puissance indiquée par le wattmètre, toutes les 5 secondes. Pendant que quelqu’un relève ces puissances, quelqu’un d’autre peut se charger d’afficher des choses différentes sur l’écran, comme par exemple 20 secondes une image avec un fond sombre, 20 secondes avec un fond clair, etc. (pour bien faire, notez au fur et à mesure ce que vous affichez, le type de couleurs, etc.).
  • Mettez l’écran en veille pendant 30 secondes et continuez à relever les puissances toutes les 5 secondes.
  • Éteignez complètement l’écran et continuez la mesure pendant 30 secondes environ.

En mode affichage de puissance, le wattmètre nous donne deux indications de valeurs de puissances, la puissance apparente et la puissance réelle. Laquelle faut-il considérer ?

En fait, les données relevées par le wattmètre à chaque seconde sont les suivantes :

  • l’estampille temporelle (l’horaire, quoi) \(t\) ;
  • la tension \(U\) (en volts) ;
  • l’intensité \(I\) (en ampères) ;
  • le facteur de puissance \(\lambda\) (sans unité).

Il n’y a pas ici d’information de puissance, mais en fait, ces données sont suffisantes pour calculer cette information. Comme nous l’avons rappelé dans la note précédente, la puissance électrique peut être calculée comme le produit de la tension et de l’intensité, \(U \cdot I\). En fait, pour un courant alternatif (en régime sinusoïdal, comme ce qui sort de notre prise de courant), cette formule nous donne la puissance apparente \(S\), qui n’est pas celle qui nous intéresse ici.

La puissance qui nous intéresse est la puissance réelle \(P\), qui est calculée en fonction de la puissance apparente \(S\) et du déphasage entre le courant et la tension \(\varphi\) : \(P = S \times \cos{\varphi}\). La valeur \(\cos{\varphi}\) est exactement ce que l’on appelle le facteur de puissance.

En d’autres termes, ici, on a : \(P = U \cdot I \cdot \lambda\).

Question 6 : relevez toutes les valeurs que vous avez notées dans un fichier CSV au format suivant :

  • séparateur de colonnes : ,
  • colonne 1 : estampille temporelle au format YYYY-MM-DD hh:mm:ss (reconstruisez cette estampille temporelle à partir de l’heure approximative de début de votre expérimentation, et de votre fréquence d’échantillonnage)
  • colonne 2 : valeur de consommation relevée (en watts)

Question 7 : Si tout se passe bien, vous avez obtenu à la question précédente des données au format à peu près similaire à ce qui suit :

2022-03-10 16:35:00,11.0
2022-03-10 16:36:05,11.0
2022-03-10 16:37:10,11.2
2022-03-10 16:38:15,11.0
2022-03-10 16:39:20,11.2
2022-03-10 16:40:25,12.2
[...]

Écrivez deux scripts Python ayant respectivement pour objectif :

  1. de calculer l’énergie totale consommée entre deux estampilles temporelles ;
  2. de tracer la courbe des mesures contenues dans le fichier (vous pourrez par exemple utiliser pyplot pour cela).

Utilisez le premier script pour compléter la cinquième colonne de la table 1.

Question 8 : rebranchez le wattmètre sur la prise de l’ordinateur que vous utilisez. Cela vous servira à la toute dernière partie de ce TP.

Émissions de gaz à effet de serre

L’électricité est obtenue par transformation d’une source d’énergie primaire, typiquement combustion d’énergie fossile ou turbinage actionnée par le vent ou l’eau. Dans chaque pays, ces moyens de production d’électricité sont différents et ont des émissions de gaz à effet de serre très différents. En France, les émissions de CO2 moyens correspondant à chaque kWh produit peuvent être trouvés sur https://www.rte-france.com/eco2mix/les-emissions-de-co2-par-kwh-produit-en-france.

Question 9 : Remplissez la table ci-dessous (la deuxième colonne correspond aux mesures faites précédemment et relevées dans la table 1)

Appareil Puissance mesurée Eq CO2 pour 1h de fonctionnement Eq CO2 pour une utilisation mensuelle typique (que vous estimerez)
PC fixe
Ordinateur portable, batterie en charge
Ordinateur portable, batterie chargée
Chargeur de portable seul
Écran plat
Téléphone en charge

Question 10 : Calculez l’équivalent carbone des mêmes appareils pour l’Allemagne, la Pologne et la Suède en vous appuyant sur les chiffres trouvés là : http://www.electricitymap.org.

Question 11 : À combien de kilomètres parcourus en voiture correspond, en terme d’émission de CO2, le fonctionnement de tous les ordinateurs fixes de la salle pendant un mois ? Considérez qu’une voiture émet environ 218 g eq.CO2 par km (source : Base Carbone de l’Ademe pour une voiture à motorisation moyenne, 2018), et prenez des hypothèses quant au nombre d’heures d’activité des machines.

Partie 2 : Jouons un peu avec les sondes logicielles

Dans cette section, nous allons nous pencher plus en détails sur la consommation de programmes, en utilisant essentiellement des sondes logicielles. Ce que l’on appelle « sonde logicielle » ici est un petit bout de code implanté sur la machine au niveau logiciel, et qui nous permet d’avoir accès à une estimation de la consommation électrique de certains composants. Comme nous allons le voir, la fiabilité de ces sondes n’est pas garantie. Il faut don prendre les informations fournies par ces sondes pour ce qu’elles sont, à savoir un ordre de grandeur permettant de donner quelques indications sur les consommations relatives de différents programmes.

Nous allons dans ce TP utiliser une bibliothèque Python permettant d’exploiter ces sondes logicielles pour faire du relevé de consommation : il s’agit de PyJoules. Il vous faudra probablement l’installer sur les machines. Un petit pip3 install pyjoules devrait faire l’affaire.

Je vous ai écrit une petite documentation sur la manière dont les sondes logicielles fonctionnent (essentiellement sous Linux) ; je vous invite fortement à aller y faire un tour.

Jouons un peu avec le tri sélectif

Question 12 : Si vous avez eu la curiosité d’aller voir ma documentation référencée ci-dessus, vous avez peut-être vu qu’il contient un cas d’utilisation complet sur la comparaison d’algorithmes de tri. Essayez de lancer ce cas d’utilisation sur votre machine, afin de retrouver les ordres de grandeur indiqués. Jouez un peu avec les paramètres, et essayez avec d’autres algorithmes de tri si vous voulez.

NB : Selon votre machine, vous devrez peut-être installer quelques bibliothèques en plus. Ça ne devrait pas vous poser de problème ; pip est votre ami.

Jouons un peu avec BPI : « C’est linéaire, et alors ? »

(citation de titre extraite du dernier opus de F. Broquedis, enseignant BPI, qui revient sur le devant de la scène après son album « C’est exponentiel, et alors ? »)

Toute ressemblance de la section ci-dessous avec une situation réelle ne pourrait être que purement fictive, et en tout cas indépendante de la volonté de M. Selva (alias El Profesor) qui n’y est pour rien dans cette affaire.

Passons à une petite application concrète. Vous enseignez désormais les Bases de la Programmation Impérative à vos collègues de 1ère année. Vous leur avez donné un petit exercice classique de programmation : recherche d’une valeur dans une liste triée. Pour cet exercice, vous leur avez donné le squelette de code suivant :

def recherche(tab, a_rechercher):
    """
    Recherche une valeur dans une liste triée.
    
    :param tab: une liste (list Python) triée.
    :param a_rechercher: la valeur à rechercher
    :returns: True si la valeur est bien dans la liste,
        et False sinon. Si la liste tab n'est pas triée
        alors le comportement de cette fonction n'est pas
        garanti.
    """
    ...

Vous avez récupéré les travaux de 5 élèves. Tous ces travaux sont fonctionnellement corrects (dans le sens où ils renvoient la bonne valeur), mais les algorithmes utilisés sont tous différents :

  • Élève 1 : une recherche linéaire (on parcourt tous les éléments du tableau dans l’ordre, jusqu’à trouver le bon).
  • Élève 2 : une recherche dichotomique récursive, en utilisant des tranches de tableau (slices, du type tab[i:j]).
  • Élève 3 : une recherche dichotomique itérative, en utilisant des tranches de tableau (slices, du type tab[i:j]).
  • Élève 4 : une recherche dichotomique récursive, sans trancher de liste.
  • Élève 5 : une recherche dichotomique itérative, sans trancher de liste.

Toutes ces solutions ne sont probablement pas égales en termes de performances. Vous cherchez un moyen d’expliquer poliment aux élèves concernés que leur code est nul. Vous décidez donc de faire des relevés de consommation pour ces cinq codes, et de faire des comparaisons.

Question 13 : Écrivez une implémentation Python de ces cinq codes et testez simplement qu’ils fonctionnent sur des tableaux aléatoires.

Question 14 : Implémentez la fonction de test suivante.

def test_recherche(tab, fonction_recherche, nb_elements):
    """
    Recherche un certain nombre d'éléments aléatoires dans un tableau.
    
    :param tab: une liste (list Python) triée.
    :param fonction_recherche: une fonction de recherche d'élément dans
        un tableau.
    :param nb_elements: nombre d'éléments à rechercher. La fonction doit
        tirer aléatoirement nb_elements (qui sont dans le tableau ou pas)
        et utiliser la fonction de recherche pour chercher ces éléments.
    :returns: None
    ...

Question 15 : Instrumentez toutes vos fonctions de recherche avec les annotations pyJoules, et écrivez une fonction principale qui génère un tableau aléatoire (trié) et lance test_recherche. Vous pouvez vous inspirer de ce qui a été fait dans le cas d’utilisation tri pour écrire cette fonction, et exporter les données de consommation de manière à les visualiser.

Question 16 : Jouez un peu avec les paramètres, et préparez un argumentaire solide pour expliquer aux élèves concernés par les plus mauvais résultats qu’ils repasseront BPI en session 2.

Fiabilité de RAPL

Comme je le disais en préambule de cette partie, même si les sondes logicielles donnent une indication de consommation électrique, elles ne fournissent aucune garantie réelle sur la pertinence des valeurs fournies. Nous allons dans cette section tâcher d’évaluer dans quelle mesure ces valeurs reflètent la consommation réelle de la machine. Ça tombe bien, nous avons des wattmètres à disposition.

Il convient de noter qu’une bonne partie de la consommation électrique échappe au domaine de mesure des compteurs RAPL, notamment tout ce qui concerne les périphériques, les supports de stockage type disques durs, etc.

Cela peut expliquer en grande partie les différences observées.

Dans cette partie, plutôt que d’utiliser pyJoules, nous allons lire directement les valeurs dans les fichiers qui vont bien (NB : c’est exactement ce que fait pyJoules en fait). Les fichiers concernés sont tous les fichiers du dossier /sys/devices/virtual/powercap/intel-rapl/. Sur les machines de l’Ensimag, il n’y a qu’un seul sous-domaine (ça peut varier selon les machines) : interl-rapl:0. C’est donc dans ce répertoire que nous allons regarder les valeurs.

Le fichier qui contient les valeurs de consommation d’énergie est le fichier energy_uj. Comme son nom l’indique, il contient la quantité d’énergie consommée depuis un certain temps (probablement le démarrage de la machine), exprimée en µJ. Pour connaître la quantité d’énergie dépensée pendant un certain temps, il suffit donc de lire la valeur indiquée par ce fichier au début et à la fin de notre période de mesure, et de faire une différence.

Question 17 : Écrivez un petit script (en bash par exemple) permettant d’aller lire périodiquement la valeur indiquée dans le fichier energy_uj, tous les \(n\) millisecondes, et d’afficher dans la console, à chaque relevé, une ligne au format CSV suivant :

  • séparateur de colonnes : ,
  • colonne 1 : estampille temporelle au format YYYY-MM-DD hh:mm:ss
  • colonne 2 : valeur de puissance moyenne relevée (en watts) − vous l’avez compris, cette valeur correspond à la différence entre deux valeurs successives de energy_uj, divisée par le temps entre les deux mesures. Attention, il vous faudra faire la conversion µJ → Wh avant de convertir en watts.

Allez, je suis sympa, je vous donne la conversion joules → wattheures. 1 Wh = 3600 J.

Question 18 : Votre wattmètre est encore branché sur la prise électrique d’alimentation du PC fixe. Ça tombe bien, vous allez l’utiliser maintenant. Faites comme en Question 5 et mesurez la puissance relevée par le wattmètre pendant 1 ou 2 minutes, toutes les 5 secondes. En parallèle (c’est-à-dire en même temps), lancez le script de relevé des valeurs élaboré à la question suivante.

Question 19 : Relevez dans un fichier CSV toutes les valeurs notées, au même format que précédemment. Lancez vos scripts de visualisation et de calcul de l’énergie électrique consommée sur les deux jeux de données (relevés manuels au wattmètre et relevés automatiques des compteurs RAPL). Les valeurs sont-elles cohérentes ?

Comparaison avec CodeCarbon

CodeCarbon1 est une autre bibliothèque Python permettant de faire de la mesure de consommation énergétique à l’aide de sondes logicielles. Plus précisément, l’objectif de la bibliothèque est de réaliser une estimation de l’impact carbone d’un code Python, en s’appuyant sur des mesures de consommation énergétique (dont RAPL, tout comme PyJoules, lorsque ces sondes sont disponibles). Vous pourrez trouver quelques explications sur l’utilisation de CodeCarbon dans ma petite documentation sur les sondes logicielles référencée ci-dessus, de même que sur le dépôt de la bibliothèque.

Dans cette partie, nous allons vérifier que les deux bibliothèques (PyJoules et CodeCarbon) fournissent des résultats cohérents.

Question 20 : imaginez un protocole expérimental permettant de comparer les résultats donnés par CodeCarbon à ceux fournis par PyJoules sur les mêmes jeux de test que dans les questions 13 à 16 (recherche dans une liste triée), implantez ce protocole, et analysez les résultats fournis. Les valeurs sont-elles cohérentes ?

Partie 3 : Bon, j’ai consommé quoi aujourd’hui ?

Vous vous souvenez du wattmètre que l’on avait laissé branché à la première partie ? Eh bien en fait il permet d’enregistrer les données en mémoire et de les transférer sur une carte SD.

Vous pouviez pas me le dire ?

En fait, si nous ne l’avons pas fait à la partie 1, c’est que la fréquence de stockage des valeurs du wattmètre est malheureusement bien trop faible : 1 toutes les minutes. On ne peut pas observer grand chose pour une expérimentation qui dure très peu de temps. En revanche, on peut utiliser le wattmètre pour faire des relevés sur le temps long, ce qui a un intérêt certain. Aujourd’hui, nous allons utiliser ce mécanisme pour essayer de déterminer ce que nous a coûté ce TP.

Question 21 : Pour relever les données, procédez comme suit :

  • Débranchez le wattmètre et insérez une carte SD dans le compartiment latéral.
  • Branchez le wattmètre.
  • Lorsque l’affichage s’allume, appuyez sur la touche ▶
  • Lorsque l’indicateur de mémoire passe à 99 %, débranchez le wattmètre. Les données sont transmises.

Récupérez les données (fichiers d’extension .BIN) sur un ordinateur.

Question 22 : Les données que vous avez récupérées sont au format binaire. Si vous savez lire directement le binaire, tant mieux pour vous (vous êtes peut-être un robot). Si comme moi, vous ne savez pas, il vous faudra une bibliothèque pour les extraire sous un format exploitable. Regardez du côté de https://github.com/Lekensteyn/el4000.

Si vous utilisez cette bibliothèque, il suffit que vous exportiez vos données avec l’option -p watts, et vous récupérez directement vos données au même format que celui que je vous ai demandé en question 6. Réutilisez donc les scripts écrits en Question 7 pour visualiser les valeurs de puissance et calculer l’énergie totale consommée pendant le TP.


  1. https://github.com/mlco2/codecarbon↩︎