Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

La bombe Parallèle ! PLINQ, et PCP Parallel Computing Platform

Le framework .NET n'en finit pas d'innover ! La bombe du jour c'est PLINQ et PCP.

Vous ne connaissez pas encore ? Normal, ce n'est même pas encore sorti, juste en preview...

Pour résumer en un mot : Révolutionnaire. Comme LINQ.

L'objectif

Vous l'avez certainement remarqué comme tout geek qui se respecte, depuis quelques années nos amis fondeurs ne se battent plus à coup de Ghz pour promouvoir leurs microprocesseurs... Les gammes se multiplient et surtout les coeurs ! Et le temps où le concepteur d'un soft trop lent pouvait toujours dire "je suis en avance c'est tout, avec la dernière génération de processeur mon soft est super rapide!", ce temps là est fini, révolu.

Aujourd'hui un soft lent sur un dual core sera peut être même encore plus lent sur un quad core d'une autre série (il y a plein de séries de processeurs on ne s'y retrouve d'ailleurs plus pour choisir...).

Donc, pour qu'un soft soit plus rapide, inutile de compter sur la prochaine génération de processeur qui doublera la fréquence d'horloge. Aujourd'hui on double le nombre de coeurs, c'est tout. un, puis deux, les quatre coeurs se banalisent, Intel avait annoncé (le tiendront ils) que d'ici peu de temps on atteindrait les 100 coeurs... Mais pour tirer partie de tous ces coeurs finalement pas si rapide, une seule solution le parallélisme !

Parallèlisme et programmation

Seulement voilà, pour bénéficier de tous ces coeurs il faut programmer selon un mode parallèle. Le plus "simple" consiste à faire du multi-threading en laissant l'OS répartir les threads entre les coeurs, mais pour plein de raison (je vous laisse y réfléchir) cela n'est pas forcément optimal. Un simple exemple : une tâche un peu lourde, vous n'avez pas besoin de 50 threads, vous avez une grosse bonne boucle qui traite une image pour faire du morphing par exemple. Allez programmez ça en créant plusieurs threads ! Si vous y arriver sans y engloutir des semaines de mise au point, je veux bien manger mon chapeau (il faudra fournir le chapeau je n'en porte pas, et si vous le fournissez, ça ne sera pas le mien, donc je ne le mangerais pas. On ne m'a pas si facilement...) !

Car en effet, multiplier les threads n'est pas toujours réalisable, en tout cas simplement. Découper une tâche en sous tâches parallélisables est en réalité tellement complexe, surtout de façon générique, que les langages et les OS sont bien à la traîne par rapport aux microprocesseurs. A la traîne ? Pas tous... Car sous .NET il va falloir compter avec PLINQ et PCP !

PLINQ et PCP

En très gros il s'agit d'extensions du framework .NET qui permet de paralléliser à peu près tout traitement sans presque aucune programmation particulière. Oui vous avez bien lu...

Ainsi, PLINQ est une extension parallèle de LINQ. Une requête LINQ comme :

var result = from c in liste where c.champ==5 orderby c.autreChamp select c; // version simple

devient en parallèle :

var result = from c in liste.AsParallel() where c.champ==5 orderby c.autreChamp select c; // parallélisée

Et c'est tout ! D'un seul coup la requête devient parallèle et s'executera sur tous les coeurs disponibles à la fois, le boulot étant découpé, les threads créés, et tout le reste, de façon automatique par PLINQ. Un rêve ? Non, pas besoin de se pincer, c'est déjà en preview à télécharger ! (voir en fin de billet).

Bien entendu il existe beaucoup de variantes et une syntaxe appropriée pour, par exemple, modifier le nombre de coeurs utilisés et plein d'autres nuances subtiles.

La parallélisation de LINQ est une pure merveille, mais il y a aussi PCP qui est le framework plus généraliste permettant de paralléliser des foreach, des for, etc, juste avec un mot clé. Il existe là aussi toute une panoplie de méthodes qu'il va falloir découvrir. Mais vous avouerez que le bond en avant est aussi fantastique que celui de LINQ par exemple. Je ne pense sincèrement pas que quiconque ayant utilisé LINQ ne voudra dans l'avenir d'un langage ne supportant pas une telle extension. Il y a eu un avant LINQ, il y aura forcément un après LINQ, mais on ne traversa pas le temps sans faire référence à cette nouvelle ère, au sens premier, le clou d'airain planté par le prêtre dans la mur du temple de la Rome antique pour marquer un événement crucial d'une telle importance qu'une nouvelle série d'années commençait.

PLINQ et PCP marqueront de la même façon une nouvelle ère.

Faire joujou ?

Je reconnais bien le geek qui sommeille en vous ! Oui c'est possible ! Il existe une CTP sortie en juin et qui est téléchargeable sur le site MSDN consacré à la programmation parallèle. Vous y trouverez de nombreuses informations qui complèteront facilement la très rapide présentation faite ici.

Le site : http://msdn.microsoft.com/fr-fr/concurrency/

... Vous êtes encore là ? Mais foncez je vous dit, c'est l'éclate du geek ce truc ! (mais pensez à revenir hein.. Stay Tuned !) Wink

[EDIT: lire aussi ce billet plus récent qui donne l'adresse d'un article sur PFX et de plusieurs Webcasts]

Les 101 exemples de LINQ à portée de clic !

LINQ.. Je vous en parle très souvent car cela en vaut largement la peine. L'essayer c'est l'adopter, surtout que ses diverses moutures (Linq to XML, Linq to SQL, Linq to Object...) peuvent trouver leur place et rendre service dans tout type de développement.

Articles, astuces, j'ai beaucoup écrit sur LINQ et ce n'est certainement pas terminé. Mais il ne faudrait pas oublier les "101 exemples pour LINQ" créés par Microsoft.

A ma connaissance il n'existe pas de traduction, cela n'existe qu'en anglais. Mais c'est une belle visite de la syntaxe de LINQ et certainement un complément indispensable à une autoformation sur le sujet.

Ces exemples ne sont pas très récents mais je me suis rendu compte que peu de développeurs les connaissaient, au moins en France. D'où l'intérêt de rappeler leur existence.

Pour la petite histoire, le chef de projet qui a écrit ces exemples a touché $202 de la part de Anders... En effet, lorsqu'il a fallu écrire les exemples, Anders était assez pressé de voir le travail fini et avait promis $2 pour chaque exemple qui serait terminé à la dead-line, une sorte de plaisenterie. Le jour fatidique, arrivé en réunion, le chef de projet en avait réalisé 101. Anders a alors fouillé ses poches et a fait l'appoint, 101x2 = $202 qu'il a remis au gars un peu gêné, ne sachant s'il devait accepter ou pas... Ce bon chef de projet a utilisé la somme pour inviter le soir même les développeurs de son équipe au resto. Une belle histoire non ? :-)

PS: Vous pouvez aussi télécharger d'autres exemples Linq en cliquant ici [edit: en novembre 2012 le site pointé n'existe plus, sorry]. Ce n'est pas très récent (Ctp de mars 2007) mais pour ceux qui prennent Linq au vol plutôt qu'à ses débuts, il est fort probable, si vous êtes dans ce cas, que vous soyez passé à côté de ce téléchargement...

PS2: Si vous voulez faire tourner le code des 101 exemples LINQ, vous trouverez sur le site pointé par le lien donné en début d'article le code de la méthode GetProductList(). Ce code est assez exotique et ne compile pas. Il faut le modifier pour en tirer quelque chose. Pour vous simplifier la vous trouverez ci-après une unité de code C# contenant une définition correcte de cette fonction, encapsulée dans une classe abstraite. Cela devrait vous aider... Data.rar (2,26 kb)

Donner du peps à Linq ! (Linq dynamique et parser d'expressions)

J'ai eu moulte fois ici l'occasion de dire tout le bien que  je pense de LINQ, de sa puissance, de sa souplesse, de sa versatilité (de xml à SQL en passant par les objets et l'Entity Framework).

Mais une petite chose me chagrinait : toute cette belle puissance s'entendait "hard coded". Je veux dire par là que les expressions et requêtes LINQ s'écrivent en C# dans le code et qu'il semblait très difficile de rendre la chose très dynamique, sous entendu dépendant d'expressions tapées à l'exécution de l'application. En un mot, faire du LINQ dynamique comme on fait du SQL dynamique.

Ce besoin est bien réel et ne concerne pas que les sources SQL. Prenez une simple liste d'objets que l'utilisateur peut vouloir trier selon l'une des propriétés ou filtrer selon le contenu des objets... Comment implémenter une telle feature ?

Contourner ce manque en écrivant des parsers, en jonglant avec les expressions lamba et la réflexion n'est pas, il faut l'avouer, ce qu'il y a de plus simple. Mais rassurez-vous chez Microsoft des gens y ont pensé pour nous ! Seulement voila, la chose est assez confidentielle il faut bien le dire, et on ne tombe pas dessus par hasard. Ou alors c'était un jour à jouer au Lotto, voire à contrôler, selon les mauvaises langues, l'emploi du temps de sa femme !

La chose s'appelle "LINQ Dynamic Query Library", un grand nom pour une petite chose puisqu'il s'agit en réalité d'un simple fichier source C# à ajouter à ses applications.  Mais quel fichier source !

Toute la difficulté consiste donc à savoir que ce fichier existe et mieux, où il se cache... C'est là que c'est un peu vicieux, la chose se cache dans un sous-répertoire d'un zip d'exemples Linq/C#, fichier lui-même astucieusement planqué dans la jungle des milliers de téléchargement de MSDN...

Sans plus attendre allez chercher le fichier cliquant ici.

Une fois que vous aurez accepté les termes de la licence ("I Accept" tout en bas à gauche) vous recevrez le fichier "CSharpSamples.zip". Dans ce dernier (dont tout le contenu est vraiment intéressant) aller dans le répertoire "LinqSamples" puis dans le projet "DynamicQuery" vous descendrez dans une autre sous-répertoire appelé lui aussi "DynamicQuery" (non, ce n'est pas un jeu de rôle, juste un téléchargement MSDN!). Et là, le Graal s'y trouve, "Dynamic.cs".

Copiez-le dans vos projets, et ajouter un "using System.Linq.Dynamic". A partir de là vous pourrez utiliser la nouvelle syntaxe permettant de faire du LINQ dynamique. A noter que dans le répertoire de la solution vous trouverez aussi un fichier "Dynamic Expressions.html" qui explique la syntaxe du parser.

Quelles sont les possibilités de LINQ Dynamic Query Library ?

C'est assez simple, pour vous expliquer en deux images je reprend deux captures écrans tirées du blog de Scott Guthrie (un excellent blog à visiter si vous parlez l'anglais).

Voici un exemple de requête LINQ (en VB.NET, si j'avais refait la capture cela aurait été du C#, mais je ne vais pas rouspéter hein ! )

Maintenant voici la même requête utilisant du LINQ dynamique :

Vous voyez l'astuce ? Le filtrage et le tri sont maintenant passés en chaîne de caractères... Bien entendu cette chaîne peut avoir été construite dynamiquement par code (c'est tout l'intérêt) ou bien saisie depuis un TextBox rempli par l'utilisateur.

Ici pas de risque d'attaque par "SQL injection", d'abord parce que LINQ n'est pas limité à SQL et que le problème ne se pose que dans ce cas, mais surtout parce que LINQ to SQL utilise des classes issues d'un modèle de données "type safe" et que par défaut LINQ to SQL est protégé contre les attaques de ce type. Pas de souci à se faire donc.

Pour terminer j'insisterai lourdement sur le fait que LINQ ne se limite pas aux données SQL, et que l'astuce de LINQ dynamique ici décrite s'applique même à LINQ to Object par exemple. Laisser la possibilité à un utilisateur de trier une List<> ou une Collection<>, de la filtrer, tout cela en mémoire et sans qu'il y ait la moindre base de données est bien entendu possible.

LINQ est vraiment une innovation majeure en matière de programmation, pouvoir le dynamiser simplement c'est atteindre le nirvana...

Je vous laisse vous jeter sur vos claviers pour expérimenter du LINQ dynamique, amusez-vous bien !

..et surtout.. Stay tuned !

 

LINQ à toutes les sauces !

Je suis en train de boucler mon article de présentation de LINQ. Au départ je pensais m'en sortir en une dizaine de pages, mais j'en suis à plus du double... juste pour faire le tour des principales possibilités et sans détailler la syntaxe (ce n'est pas le but de cet article).

J'ai eu maintes fois l'occasion de vous dire ici que LINQ est l'innovation la plus fantastique que j'ai vue depuis longtemps dans un langage. Vous en saurez plus en lisant le prochain article qui sera en ligne ce week-end, mais pour vous prouver que LINQ peut servir partout et tout le temps voici deux exemples à contre-courant de l'idée qu'on se fait des utilisations possibles de LINQ :

Cas 1 : Lister les services actifs de Windows.

C'est bête mais balayer et filtrer une simple liste comme celle là (et de bien d'autres du même genre retournées par le framework .NET ou par vos applications), c'est produire du code pas très marrant... Avec LINQ ça devient :

using System.ServiceProcess; 
var srv = from s in ServiceController.GetServices()
         where s.Status == ServiceControllerStatus.Running
         select s.DisplayName;
ListBox1.DataSource = srv.ToList();

 
Je trouve ça élégant, pas vous ?

Cas 2 : Remettre à unchecked tous les Checkbox d'une form

Balayer certains contrôles d'une fiche n'est là non plus pas l'endroit où l'on s'attend à trouver du LINQ... Et pourtant ! Imaginons une fiche de saisie avec des tas de checkbox et un bouton "raz" de remise à zéro de la fiche. Balayer tous les contrôles de la fiche pour ne sélectionner que les checkbox n'est pas un code bien complexe mais avec LINQ ça devient tellement plus chouette !

var cb = (from Control c in this.Controls select c).OfType<CheckBox>();
foreach (var c in cb) c.Checked=false;
 

C'est pas plus joli et plus clair écrit comme ça ? (et encore on pourrait se passer de la variable "cb" et intégrer directement la requête LINQ après le "in" du "foreach")?

Bref, LINQ j'adore. Et j'espère bien que le papier à venir va vous transformez en fans vous aussi ! alors... Stay tuned !

Les nouveautés syntaxiques de C# 3.0

Les expressions Lambda vous connaissez ?

Et l'inférence des types locaux, les méthodes d'extension, les expressions d'initialisation des objets ou les types anonymes ?

Si tout cela sonne bizarrement à vos oreilles, n'hésitez plus une seconde : téléchargez le nouvel article que j'ai mis en ligne gratuitement !

Voici le lien, il n'y a qu'à cliquer ici !

Vous êtes encore là ?

... Alors ne loupez pas le tout dernier article "Présentation de LINQ avec C#", un papier de 32 pages riche en exemples !