Blog de JP Gouigoux

21/03/2009

Programmation parallèle en .NET

Filed under: .NET — jpgouigoux @ 8:21

Un petit test de la parallélisation en .NET, avec la CTP de Juin 2008 des Parallel Extensions.

A utiliser, c’est très simple : on utilise une nouvelle librairie System.Threading, qui rajoute des opérateurs parallélisés ainsi que des listes supportant la parallélisation.

Voici un petit bout de code pour tester sur un AMD 64X2 4400+, avec donc deux coeurs :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace TestParallelisation
{
class Program
{
static void Main(string[] args)
{
List Entiers = new List();

for (int ind = 100000; ind < 120000; ind++) Entiers.Add(ind); Stopwatch Chrono = Stopwatch.StartNew(); List Premiers = new List();

foreach (int Entier in Entiers)
if (EstPremier(Entier))
Premiers.Add(Entier);
Console.WriteLine(« {0} premiers trouvés en {1} ms », Premiers.Count, Chrono.Elapsed.Milliseconds);

 Chrono = Stopwatch.StartNew();
List PremiersSynchro = new List();
Parallel.ForEach(Entiers, i => { if (EstPremier(i)) PremiersSynchro.Add(i); });
Console.WriteLine(« {0} premiers trouvés en {1} ms », PremiersSynchro.Count, Chrono.Elapsed.Milliseconds);
}

private static bool EstPremier(int Nombre)
{
for (int ind = 2; ind < Nombre - 1; ind++) if (Nombre % ind == 0) return false; return true; } } } [/sourcecode] On voit qu'on cherche la liste des nombres premiers entre 100 000 et 120 000, avec une première version standard, et qui s'exécutera donc sur un seul core, et une seconde permettant la parallélisation. Ici, rien de compliqué puisque chaque nombre est traité séparément, donc c'est très simple de répartir sur autant de processeurs que nécessaire. Les résultats : 539 ms en mono-core, 388 ms en parallèle sur deux cores. Une amélioration de performance d'environ 30%, en informatique, c'est déjà pas mal... Et imaginez sur un octo-core. Les résultats varient un peu en fonction du temps, mais on a une bonne idée du ratio sur ce type d'algo. Toutefois, un bug est présent dans ce code : on écrit les résultats dans une liste d'entiers, et le multithread peut faire que les résultats sont écrits en même temps, résultant en des écrasements, que j'ai pu constater sur un test avec un résultat de référence de 1709 entiers premiers, et 1708 seulement sur le deuxième. Le premier réflexe est de créer plusieurs listes et de les grouper à la fin, mais comment faire quand on n'a pas la main sur le nombre de threads ? Après recherche sur internet, il se trouve que Microsoft a tout prévu. Au lieu d'utiliser des listes génériques, il faut utiliser System.Threading.BlockingCollection<T>, qui est faite spécialement pour ça... Bref, un premier essai convaincant !

Publicités

Le chou fractal… suite

Filed under: Divers — jpgouigoux @ 7:57

Je ne suis visiblement pas le seul à être étonné par cette organisation fractale des branches de chou…

http://www.psy.ritsumei.ac.jp/~akitaoka/machika4e.html

Propulsé par WordPress.com.