Exercice – Apprivoiser la multiprogrammation

Quelques exercices pour apprivoiser la multiprogrammation avec C#.

Quelques exercices

Voici quelques exercices que je vous recommande de faire. Prenez soin de tester chacune de vos réponses (faux partage, zone transit, pipeline, somme des impairs)

EX00 – Soit le programme suivant :

using System;
using System.Diagnostics;
// ...
static short[] CréerTableau(int n)
{
   short [] tab = new short[n];
   for(int i = 0; i != tab.Length; ++i)
      tab[i] = (short)(i * 2 + 1);
   return tab;
}
static int CompterSi(short [] tab, Func<short, bool> pred, int hauteur, int largeur)
{
   int n = 0;
   for(int ligne = 0; ligne != hauteur; ++ligne)
      for(int colonne = 0; colonne != largeur; ++colonne)
         if(pred(tab[ligne * hauteur + colonne]))
            ++n;
      return n;
}
static (T rés, long dt) Tester<T>(Func<T> f)
{
   var sw = new Stopwatch();
   sw.Start();
   T rés = f();
   sw.Stop();
   return (rés, sw.ElapsedMilliseconds);
}
static void Main()
{
   const int N = 25_000;
   var tab = CréerTableau(N * N);
   var (r0, dt0) = Tester(() => CompterSi(tab, n => n % 2 != 0, N, N));
   Console.WriteLine($"Compté {r0} impairs en {dt0} ms");
}

EX00.0 : notez le temps d'exécution de ce programme en Release, puis dans la fonction CompterSi, inversez l'ordre des deux boucles (passez de ligne, colonne à colonne, ligne) et examinez le résultat affiché. Que remarquez-vous?

EX00.1 : avec la plus rapide des deux versions de CompterSi, modifiez ce programme pour qu'il utilise deux fils d'exécution, puis quatre, puis huit. Assurez-vous qu'il affiche la bonne réponse à chaque fois. Votre code devient-il plus rapide quand on ajoute des fils d'exécution? Note : pour vous rendre la vie plus agréable, réécrivez CompterSi pour qu'elle ait la forme suivante :

using System;
using System.Diagnostics;
// ...
static short[] CréerTableau(int n)
{
   short [] tab = new short[n];
   for(int i = 0; i != tab.Length; ++i)
      tab[i] = (short)(i * 2 + 1);
   return tab;
}
static int CompterSi<T>(T [] tab, Func<T, bool> pred, int début, int fin) // début inclus, fin exclue
{
   int n = 0;
   for(int i = début; i != fin; ++i)
      if(pred(tab[i]))
         ++n;
   return n;
}
static (T rés, long dt) Tester<T>(Func<T> f)
{
   var sw = new Stopwatch();
   sw.Start();
   T rés = f();
   sw.Stop();
   return (rés, sw.ElapsedMilliseconds);
}
static void Main()
{
   const int N = 25_000;
   var tab = CréerTableau(N * N);
   var (r0, dt0) = Tester(() => CompterSi(tab, n => n % 2 != 0, 0, tab.Length)); // début, fin
   Console.WriteLine($"Compté {r0} impairs en {dt0} ms");
}

EX01 – écrivez une classe ZoneTransit<T> contenant une List<T> et offrant deux services : Ajouter(List<T>) pour concaténer la liste en paramètre à la fin de la ZoneTransit<T>, et Extraire() retournant la List<T> dans la ZoneTransit<T> et faisant en sorte que la ZoneTransit<T> redevienne vide. Assurez-vous que les opérations Ajouter et Extraire soient synchronisées de manière à éviter que la ZoneTransit<T> ne soit corrompue. Note : vous n'avez pas le droit d'utiliser une ConcurrentQueue<T> ou une autre collection qui ferait le travail à votre place, ce serait de la triche!

EX01.0 : un collègue vous propose d'ajouter des services à votre classe, soit : AjouterUn(T) pour ajouter un seul élément à la fois à la fin de la ZoneTransit<T>; ExtraireUn() pour extraire un élément à la fois du début de la ZoneTransit<T>; une propriété EstVide et une propriété Count. Est-ce que votre collègue a une bonne idée? Expliquez votre réponse...

EX02 – à l'aide de la classe ZoneTransit<T> développée en réponse à EX01, écrivez un programme ayant les particularités suivantes :

Assurez-vous que le programme se termine normalement, que les fichiers résultants soient complets, et que les fils travaillent concurremment.

EX03 – sur la base de vos travaux en EX01 et EX02, écrivez un programme dans lequel on trouvera un pipeline transformant des fichiers .cs en fichiers .html. La forme attendue sera :

Assurez-vous que le programme se termine normalement, que les fichiers résultants soient complets, et que les fils travaillent concurremment.


Valid XHTML 1.0 Transitional

CSS Valide !