De plus en plus de personnes sont maintenant équipées de processeurs Dual Core. Les Quad Core commencent aussi à gagner de la popularité, et même les processeurs à huit coeurs (Octo Core ?) deviennent réalité. Il est très facile d'imaginer un processeur seize coeurs dans chaque nouvel ordinateur d'ici seulement quelques années.
Tout ceci est bien beau, mais pour prendre avantage de toute cette puissance, il faut que les applications soient programmées pour utiliser plusieurs threads. Ceci peut devenir très compliqué avec les techniques actuelles, et représente parfois trop de travail pour justifier les résultats. Mais lorsque les processeurs à multiples coeurs deviendront chose du commun, ces résultats seront de plus en plus impressionnants.
Afin de diminuer la complexité de la programmation multi-thread, et ainsi favoriser le développement de ce type d'applications, Microsoft travail sur une librairie très intéressante nommée Parallel Framework Extensions (PFX). Cette librairie offre des façons très simples d'accomplir certaines tâches communes dans le monde de la programmation parallèle.
Par exemple, supposons que vous avez une collection d'objets sur lesquels vous désirez effectuer un traitement. Une implémentation naïve de cela pourrait ressembler à ceci :
private void DoManipulationOnFooList(IList<Foo> data)
{
foreach (Foo f in data)
{
// Do something with f
}
}
Ce code est très simple et parfaitement acceptable lorsque l'ordinateur n'a qu'un seul processeur. Toutefois, une machine à quatre coeurs ne pourra utiliser que le quart de sa capacité pour traiter ce code.
Une meilleure implémentation serait d'utiliser le ThreadPool.
private void DoManipulationOnFooList(IList<Foo> data)
{
foreach (Foo f in data)
{
ThreadPool.QueueUserWorkItem(new WaitCallBack(delegate(object arg)
{
Foo foo = (Foo)arg;
// Do something with foo
}, f));
}
}
De cette façon, plusieurs coeurs seront utilisés. Toutefois, le code est moins élégant que la première version, et quelques problèmes peuvent survenir. Qu'arrive-t-il si une exception a lieu lors du traitement de l'un des item? Plusieurs détails doivent être considérés pour utiliser le ThreadPool, et cette méthode pourrait facilement devenir très compliquée. De plus, pour obtenir le même comportement que la première version du code, il faut ajouter un mécanisme pour empêcher DoManipulationOnFooList de retourner tant que tout le travail n'est pas terminé.
Avec PFX, une implémentation complète et très efficace de cette situation pourrait ressembler à ceci :
private void DoManipulationOnFooList(IList<Foo> data)
{
Parallel.ForEach<Foo>(data, delegate(Foo f)
{
// Do something with f
});
}
Notez qu'il ne s'agit peut-être pas de la syntaxe exacte. Je n'ai pas trouvé d'exemple concret de la méthode ForEach.
Beaucoup plus simple n'est-ce pas? Le code est très semblable à la première version, mais celui-ci utilisera efficacement tout les processeurs disponibles. La liste d'objets sera séparée entre les différents coeurs, qui travailleront chacun de leur côté. Si un processeur termine son travail avant les autres, il ira voler du travail aux autres. Les exceptions seront gérées d'une manière prévisible, et la méthode ne retournera que lorsque tout le travail sera terminé.
Bien entendu, PFX ne s'arrête pas là. Bien que cette façon de faire sera satisfaisante dans plusieurs cas, des problèmes plus compliqués demandent des méthodologies différentes. Pour ces cas, il est possible de descendre d'un niveau d'abstraction et d'utiliser des composantes plus flexibles.
Ces concepts de parallélismes ont aussi été adapté à LINQ. Avec PLINQ, vous pourrez prendre avantage de tous les processeurs de l'ordinateur lors de vos requêtes LINQ et ce, en ajoutant simplement .AsParallel() à celles-ci.
Il est difficile d'en dire plus sur ce sujet car très peu de documentation existe pour le moment. Toutefois, il s'agit d'une technologie très intéressante, et je crois bien que tous les développeurs devraient se familiariser avec cela le plus tôt possible. Je vous suggère de commencer par ce vidéo sur Channel9 qui présente un survol des bases de PFX et PLINQ.
Mise à jour, 13 mai 2008: J'ai réalisé que certains liens dans cet article ne fonctionnaient plus. Je les ai remplacés par des liens fonctionnels. Remarquez qu'un CTP de Parallel Extensions est maintenant disponnible à télécharger.
