alt.net modéliser parallèle avec c# 4.0

40
Modéliser Parallèle avec C# 4.0 21 avril 2010 Bruno BOUCARD [email protected] http://blogs.msdn.com/devpara/default.aspx http://msmvps.com/blogs/brunoboucard Code Session : TCP301

Upload: bruno-boucard

Post on 21-Jun-2015

1.171 views

Category:

Technology


2 download

DESCRIPTION

Dans cette session présentée le 21 avril 2010 à Paris dans les locaux d'OCTO Technology. Vous découvrirez les règles essentielles et les principaux patterns parallèles qui vous aideront à écrire en C# 4.0 des applications parallèles plus évolutives et plus faciles à maintenir pour retrouver le Free Lunch

TRANSCRIPT

Page 1: ALT.NET Modéliser Parallèle avec C# 4.0

Modéliser Parallèle avec C# 4.0

21 avril 2010Bruno [email protected]

http://blogs.msdn.com/devpara/default.aspxhttp://msmvps.com/blogs/brunoboucard

Code Session : TCP301

Page 2: ALT.NET Modéliser Parallèle avec C# 4.0

Méthode itérative

Choisir une stratégie et un

algorithme adaptés

Implémenter son algorithme avec un

pattern qui le supporte

Trouver la concurrence

Mesurer les performances de la

solution

Page 3: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 1

Mesurer les performances de la solution

Page 4: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 1Analyser les performances

• Analyser les coûts de la solution séquentielle

Page 5: ALT.NET Modéliser Parallèle avec C# 4.0

Analyser les performances

Démonstration

Page 6: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 2

Trouver la concurrence

Page 7: ALT.NET Modéliser Parallèle avec C# 4.0

• Terminer avec une décomposition de tâches ordonnées en fonction des dépendances techniques et fonctionnelles, compléter par les données partagées que vous aurez identifiées

• Il arrive qu’on passe d’une décomposition orientée tâches à une décomposition orientée données ou bien flux de données en fonction du type de traitement

Etape 2Trouver la concurrence

• Commencer avec un cahier des charges qui décrit le problème• Quel que soit le contexte fonctionnel ou technique, vous serez guidé

naturellement par l’une des décompositions

Evaluer le design

Grouper les tâches

Ordonner les tâches

Analyse des dépendances

Partager les données

Commencer

Analyser les dépendances- Visual Studio 2010 : Architecture -> Generate Dependency Graph- NDepend: http://www.ndepend.com/

Orientée tâches

Orientée données

Décomposition

Page 8: ALT.NET Modéliser Parallèle avec C# 4.0

Trouver la concurrence

Démonstration

Page 9: ALT.NET Modéliser Parallèle avec C# 4.0

Trouver la concurrenceSolution séquentielle

Sélectionner un

répertoire

Charger tous les noms d’images

dans le répertoire et ses sous répertoires

Twister l’image

Normaliser l’image

Convertir l’image en

une vignette

Charger une image

Dépiler un nom

de fichier

Empiler les noms de fichiers

sélectionnés

Insérer dans le contrôle graphique

WM_TIMER

Structure de pile partagée

Page 10: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 2Décomposition et granularité

• Votre décomposition en tâches doit tenir compte de leur granularité et de leur surcoût

tâche

tâche

tâche

tâche

Cœur 1

tâche

tâche

tâche

tâche

Cœur 2

tâche

tâche

tâche

tâche

Cœur 0

tâche

tâche

tâche

tâche

Cœur 3

Configuration 1

Cœur 0

tâche

Cœur 1

tâche

Cœur 2

tâche

Cœur 3

tâche

Configuration 2

Quelle est la meilleure configuration ?surcoût

charge

Page 11: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 2Décomposition et répartition de charge

• Votre groupement de tâches doit tenir compte de leur charge

tâche

tâche

tâche

tâche

Cœur 1

tâche

tâche

Cœur 2

tâche

Cœur 0

tâche

Cœur 3

Configuration 1

tâche

tâche

Cœur 1

tâche

tâche

Cœur 2

tâche

Cœur 0

tâche

Cœur 3

tâche

tâche

Configuration 2

Quelle est la meilleure configuration ?surcoût

charge

Page 12: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 2Evaluer votre design• Flexibilité

– Préférer l’abstraction pour faciliter l’adaptation à différents scénarios d’exécution

• Nombre de cœurs sollicités• Partitionnement des données

• Efficacité– Le temps dépensé à gérer le parallélisme vs le temps gagné à tirer

parti des cœurs– Amélioration des performances en fonction du nombre de

processeurs• Simplicité

– Le code peut être facilement diagnostiqué– La solution technique choisie est facile à maintenir

Page 13: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3

Choisir un algorithme en

fonction de votre stratégie

Page 14: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Choisir un algorithme en fonction de votre stratégie

Décomposition orientée

Données

Linéaires ?

Décomposition géométrique

Récursives ?

Décomposition récursive

Tâches

Linéaires ?

Parallélisme de tâches

Récursives ?

Diviser pour régner

Flux de données

Régulier ?

Pipeline

Irrégulier ?

Coordination orientée

événements

Page 15: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Algorithmes données• Décomposition géométrique

Traitement d’une collection d’images, addition de matrices …

Taille des morceaux • Trop grand – sous utilisation• Trop petit – sur consommation

Format des morceaux• Attention au false sharing

Page 16: ALT.NET Modéliser Parallèle avec C# 4.0

• Éviter l'allocation de mémoire contiguë• Deux champs d'instance dans la même instance de classe sont proches dans

leurs emplacement de mémoire • Deux champs statiques dans le même type sont proches en mémoire• Deux éléments avec des index adjacents dans un tableau sont proches en

mémoire • Les objets alloués consécutivement sont probablement proches en mémoire• Les variables locales utilisées ensemble dans une fermeture sont

probablement capturées dans les champs d'instance, et ainsi, d'après le premier commentaire ci-dessus, sont également proches en mémoire

ModéliserAlgorithmes données – Attention au False Sharing

• Pour des raisons de performances, les systèmes utilisent des lignes de cache

• Lorsque des threads sur différents processeurs modifient en parallèle les variables qui résident sur la même ligne de cache, le False Sharing n’est pas loin

Cache

Ligne de cache

Mémoire

Coeur 0 Coeur 1T0 T1

Cache

Ligne de cache

Page 17: ALT.NET Modéliser Parallèle avec C# 4.0

Algorithmes données: False Sharing

Démonstration

Page 18: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Décomposition géométrique

for (int i = 0; i < size; i++) { Parallel.For(0, size, j => { int temp = 0; for (int k = 0; k < size; k++) { temp += m1[i, k] + m2[k, j]; } result[i, j] = temp; });}

Page 19: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Algorithmes données

Décomposition récursive

Parcours de graphe ou parcours d’arbre …

2 tâches

3 tâches

3 tâches

1 tâche

Le choix de la profondeur détermine la performance- Arbre profond • contention processeurs- Arbre de profondeur limitée• sous utilisation des processeurs

Page 20: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Récursivité sur des données

static void Walk<T>(Tree<T> root, Action<T> Action){ if (root == null) return; var t1 = Task.Factory.StartNew(() => action(root.Data)); var t2 = Task.Factory.StartNew(() => Walk(root.Left, action)); var t3 = Task.Factory.StartNew(() => Walk(root.Rigth, action)); Task.WaitAll(t1, t2, t3);}

Page 21: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Algorithmes tâches• Parallélisme de tâches linéaires

Paralléliser des opérations décomposables

sous opération 4sous opération 1sous opération 2

sous opération 3

sous opération 1

sous opération 2

sous opération 3

sous opération 4

Nombre de tâches• trop peu: les cœurs sont sous utilisés• trop élevé: contention des tâchesDépendances• retirables• séparables• lecture seule ou lecture/écriture

Page 22: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Algorithmes tâches

Diviser pour régner

QuickSort

Résoudre

Problème

Sous - problème Sous - problème

Sous - problème Sous - problème Sous - problème Sous - problème

Sous - problème Sous - problème Sous - problème Sous - problème

Sous - solutionSous - solution

Solution

Split

SplitSplit

RésoudreRésoudreRésoudre

Fusionner Fusionner

Fusionner

Séquentiel

2 chemins parallèles

4 chemins parallèles

2 chemins parallèles

Séquentiel

Arbres profond • contention processeursArbres de profondeur limitée• sous utilisation des processeur

Page 23: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Diviser pour régner

static void QuickSort<T>(T[] data, int fromInclusive, int toExclusive) where T : IComparable<T>{ if (toExclusive - fromInclusive <= THRESHOLD) { InsertionSort(data, fromInclusive, toExclusive); } else { int pivotPos = Partition(data, fromInclusive, toExclusive); if (toExclusive - fromInclusive <= PARALLEL_THRESHOLD) { // NOTE: PARALLEL_THRESHOLD is chosen to be greater than THRESHOLD. QuickSort(data, fromInclusive, pivotPos); QuickSort(data, pivotPos, toExclusive); } else Parallel.Invoke( () => QuickSort(data, fromInclusive, pivotPos), () => QuickSort(data, pivotPos, toExclusive)); }}

Page 24: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Algorithmes flux de données• Pipeline

Chaîne de montage automobile

Les charges de travail des étapes• égales – pipeline linéaire• inégales – pipeline non-linéaire

Page 25: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Algorithmes flux de données

Coordination orientée événements

Traitement d’une dépêche sur un desk journalistique …

Page 26: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 3Pipeline

var input = new BlockingCollection<string>(); var readLines = Task.Factory.StartNew(() => { try { foreach(var line in File.ReadAllLines(@"input.txt")) input.Add(line); } finally { input.CompleteAdding(); } }); var writeLines = Task.Factory.StartNew(() => { File.WriteAllLines(@"output.txt", input.GetConsumingEnumerable()); }); Task.WaitAll(readLines, writeLines);

Page 27: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 4

Choisir un pattern de structure

Page 28: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 4Choisir un pattern de structures de programme

• Après avoir sélectionné votre algorithme parallèle, il faut maintenant le supporter dans votre programme

Master/Worker

Structures de programme

Boucle parallèle

Fork/Join

SPMD

Page 29: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 4Les Patterns de structures de programme• SPMD, Master/Worker, Boucle parallèle et Fork/Join

partagent les mêmes idiomes

Partitionner

Exécuter Fusionner

Page 30: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 4Fork / Join

var tasks = new Task[3];tasks[0] = new Task(() => ComputeMean());tasks[1] = new Task(() => ComputeMedian());tasks[2] = new Task(() => ComputeMode());foreach(Task t in tasks) t.Start(); Task.WaitAll(tasks);

Parallel.Invoke(() => ComputeMean(),() => ComputeMedian(),() => ComputeMode()

);

Page 31: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 4Boucle parallèle

Parallel.ForEach(stack, bitmap =>

_imagesStack.Push(ProcessBitmap(bitmap)));

var query = from bitmap in stack.AsParallel() select ProcessBitmap(bitmap);

query.ForAll(image => _imagesStack.Push(image));

Page 32: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 4Structures de programme parallèle• Appliquées dans différents contextes

– SPMD – Systèmes distribués• MPI, SOA, Grid Computing,

– Fork / Join – Orienté Tâches• TPL

– Master/Worker – Orienté Tâches• TPL

– Boucle Parallèle – Orienté Données • TPL, PLINQ

Page 33: ALT.NET Modéliser Parallèle avec C# 4.0

Structures de programme parallèle

Démonstration

Page 34: ALT.NET Modéliser Parallèle avec C# 4.0

Structures de programme parallèle Solution parallèle

Sélectionner un

répertoire

Charger tous les noms d’images

dans le répertoire et ses sous répertoires

Dépiler une

vignette

Empiler les noms de fichiers

sélectionnés

Insérer dans le contrôle graphique

WM_TIMER

Pile partagée concurrente

Twister l’image

Normaliser l’image

Convertir l’image en

une vignette

Charger une image

Collection des noms de fichiers

Page 35: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 1

Mesurer les performances de la solution

Page 36: ALT.NET Modéliser Parallèle avec C# 4.0

Etape 1Analyser les performances

• Analyser les coûts de la solution parallèle

Page 37: ALT.NET Modéliser Parallèle avec C# 4.0

Structures de programme parallèle

Démonstration

Page 38: ALT.NET Modéliser Parallèle avec C# 4.0

ConclusionQuelques suggestions pour l’implémentation

• Préférer les nouveaux outils de haut niveau d’abstraction

• Privilégier les solutions simples à maintenir– La granularité fine est souvent synonyme de

complexité

• Utiliser systématiquement des librairies thread-safe– Fiabilité == Gain de temps

• Ne jamais présumer d’un ordre d’exécution– La justesse du code est à ce prix

Page 39: ALT.NET Modéliser Parallèle avec C# 4.0

ConclusionPour retrouver le « Free Lunch »• Respecter les 4 grandes étapes

– Notamment les « analyses des dépendances » et « analyses des performances »

• Avancer de manière itérative– Difficile de trouver « la solution » du premier coup

• Si possible privilégier les capacités de monter en charge ainsi que la simplicité

• Mesurer régulièrement les performances de vos choix– Visual Studio 2010 est votre ami

• Si vos choix ne vous semblent pas satisfaisants– Oser changer votre algorithme pour augmenter ses chances de

parallélisation

• Penser Parallèle– C’est en pratiquant régulièrement la méthode présentée que vous

gagnerez en réflexes sur l’usage des Patterns parallèles les mieux adaptés à vos besoins

Page 40: ALT.NET Modéliser Parallèle avec C# 4.0

Vous n’êtes pas seul !Livres et blogues• Mes ouvrages préférés

–Programmation Parallèle• http://msmvps.com/blogs/brunoboucard

• Portail Microsoft Parallel Computing– http://msdn.microsoft.com/en-us/concurrency

• Patterns for Parallel Programming de Stephen Toub– http://www.microsoft.com/downloads/details.aspx?FamilyID=86b3d32b-ad26-4bb8-a3ae-

c1637026c3ee&displaylang=en