Does the concurrency development is green?

La question posée est simple. Est-ce que le développement parallèle permet de moins consommer d’énergie ?

Nos protocoles de tests sont simples et très artisanaux, mais cela nous donne une vue générale.

L’idée n’est pas de mesurer la consommation effective, donc de connaître ce que vous allez payer à la fin du mois, mais de comparer des pratiques de développements entre elles.

Nous utilisons un Wattmètre que l’on branche dans la prise de courant (vous en trouverez chez tout bon électricien, ou électronicien mais pas dans les grandes surfaces de bricolage)

1) Nous mesurons la consommation, lorsque le pc ne fait rien

2) Nous exécutons l’algorithme, en faisant en sorte qu’aucune autre application ne soit encours d’exécution en même temps

3) Nous mesurons sont temps d’exécution

4) Et nous mesurons sur le wattmètre, le pic d’utilisation

Dans notre exemple, nous allons mesurer la consommation en Watt (convertie en KwH) d’un ensemble de Mandelbrot développé en .NET et C# sur un PC portable dual-core et muni de 4GO de RAM

Nous comparerons trois algorithmes qui donnent rigoureusement le même résultat en termes de rendu 

Le premier algorithme est séquentiel, et manipule un objet Bitmap, pour créer des bandes à l’écran, et boucle jusqu’à la création de la fractale. Je n’utilise pas de construction de nombre complexe, mais directement l’équation algébrique.

Le nombre d’itération étant fixée à 50000, pour augmenter la charge de travail.

while (n < 50000 && Math.Sqrt((x * x) + (y * y)) < 2)

{

x1 = x * x - y * y + a;

y = 2 * x * y + b;

x = x1;

n++;

}

bmp.SetPixel(j, i, GetColor(n));

 

Le second algorithme , toujours séquentiel, mais nous l' avons optimisé.

Nous n' utilisons plus l'objet bitmap directement, mais des pointeurs, et nous ne faisons plus appel à la méthode Sqrt pour calculer la racine carré, ce qui nous évite des milliers d'appels de méthode lorsqu'on augmente le nombre d'itération.
 

byte* newPixel = (byte*)(void*)bmpData.Scan0;
//....Code omis pour plus de clarté

while (n < 50000 && (x * x) + (y * y) < 4)                        
                        {
                            x1 = x * x - y * y + a;
                            y = 2 * x * y + b;
                            x = x1;
                            n++;
                        }
                        //Ajout des pixels                       
                        Color color = GetColor(n);
                        newPixel[0] = color.B;
                        newPixel[1] = color.G;
                        newPixel[2] = color.R;
                        newPixel += 3;

En fin le troisième algorithme, utilise les bibliothèques .NET pour tirer profit de tous les coeurs disponibles.

Voici donc les résultats.

 

  Procs Watt (IDLE) Watt (PIC) Temps (ms) KwH CO2
Algo Sequ 1 39 53 148172

0,57556

4,10E-01

Algo Sequ Optim

1 39 54

46660

0,19583

1,39E-01

Algo Parallel 2 39 63

28183

0,18667

1,33E-01

 

On peut s' apercevoir que sur cette configuration, optimiser un algorithme optimisera la consommation électrique. Le faite d' utiliser pleinement les deux coeurs augmente bien la consommation d' environ 9 Watts, mais sur un temps beaucoup plus court, ce qui rapporté en KwH, diminue très légèrement celle-ci.

Peux-ton alors conclure que le développement parallèle permettrait de diminuer la consommation ?

C' est encore un peu tôt pour l' affirmer et cela dépend tellement de facteurs que l' on ne peut pas conclure sans pousser l' exercice plus loin.

D' ailleurs voyez plutôt, j' ai fait le même exercice, mais cette fois-ci sur une machine serveur, muni de 24 Coeurs (4*6 cores) et de 16 GO de mémoire.

  Procs Watt (IDLE) Watt (PIC) Temps (ms) KwH CO2
Algo Sequ 1 382 394 17250 0,05750

4,09E-02

Algo Sequ Optim

1 382 394 15253 0,05083

3,62E-02

Algo Parallel 6 382 413 3800 0,03272

2,33E-02

Algo Parallel 12 382 423 2594 0,02961

2,11E-02

Algo Parallel 24 382 453 1650 0,03353

2,39E-02

 

L' utilisation des 24 coeurs augmente sensiblement la consommation électrique, pour un temps d' exécution qui ne baisse pas proportionnellement au nombre de coeurs utilisés

Le débat est donc ouvert pour "la green dev attitude".

Dois-je développer en parallèle et utiliser le plus de ressources possibles, sachant que consommer de la CPU consomme des KWh ?

Je ne suis pas entrain de vous dire qu' il ne faut pas développer en parallèle, mais qu' il faut optimiser d' abord son code en mode séquentiel, puis ensuite optimiser son code en parallèle pour qu' il soit scalable (monte à l' échelle)

La scalabilité est le maître mot du développement parallèle. Un mauvais algorithme séquentiel, profitait chaque 18 mois de l' augmentation de la puissance des Pcs (loi de moore), un mauvais algorithme parallèle ne profitera pas de l' augmentation du nombre de coeurs.

Ici mon algorithme a atteint ses limites et n' est pas scalable. Un Speedup de 9,24 sur un 24 coeurs n' est franchement pas géniale. Mais dois-je allez plus loin ?

Honnêtement cela dépend de l' application. Pour une application de gestion traditionnelle l' utilisateur aura sans doute la même perception entre une réponse à 2,5 secondes et 1,6 secondes, sachant qu'un seuil est atteint aux environs de 3 secondes

Si vous développez une application qui vous fait gagner 100000 de cesterces à la seconde, cela vaut vraiment le coût de s' y pencher

Eric