std.parallelism

Le module std.parallelism fourni des primitives de haut-niveau pour faciliter la programmation concurrente.

parallel

std.parallelism.parallel permet de distribuer automatiquement le corps d'un foreach sur différents threads:

// mise au carré d'un tableau en parallèle
auto tab = iota(1,100).array;
foreach(ref i; parallel(tab))
{
    i = i*i;
}

parallel utilise l'opérateur opApply en interne. La méthode parallel est un raccourci pour taskPool.parallel qui est une TaskPool qui utilise le nombre de cpus - 1 threads. Créer sa propre instance de l'objet permet de contrôler le degré de parallélisme.

Il faut faire attention à ce que le corps de l'itération de parallel ne modifie pas des variables que d'autres threads pourraient utiliser.

L'option workingUnitSize spécifie le nombre d'éléments gérés par chaque thread.

reduce

La fonction std.algorithm.iteration.reduce, connue dans d'autres langages fonctionelles sous le nom de accumulate ou de fold, appelle la fonction fun(acc, x) pour chaque élément xacc est le résultat de l'appelle précédent:

// 0 est la valeur de départ
auto sum = reduce!"a + b"(0, elements);

Taskpool.reduce est une version parallèle de reduce:

// Détermine la somme des éléments d'une range
// en parallèle, en utilisant le premier élément
// de la range comme valeur de départ de acc
auto sum = taskPool.reduce!"a + b"(nums);

TaskPool.reduce sépare la range en sous-ranges qui sont réduites en parallèle. Une fois que ces résultats ont été calculés, les résultats sont réduits eux-mêmes.

task()

task est une fonction qui permet d'appeler une autre fonction, qui pourrait prendre longtemps ou qui devrait être exécutée dans son propre thread. Il peut soit être mis dans la file d'attente d'une taskpool:

auto t = task!read("foo.txt");
taskPool.put(t);

soit être directement exécuté sur un nouveau thread:

t.executeInNewThread();

Pour obtenir le résultat de la tâche, il faut appeler la méthode yieldForce de l'objet. Elle bloquera l'exécution jusqu'à ce que le résultat soit disponible.

Pour aller plus loin

rdmd playground.d