El módulo std.parallelism

El módulo std.parallelism implementa primitivas de alto nivel para implementar programación concurrente.

La función parallel

La función std.parallelism.parallel permite distribuir de forma automática el cuerpo de una sentencia foreach entre diferentes hilos de ejecución:

// Se ejecuta la operación de elevar al cuadrado
// cada elemento del array de forma paralela.
auto arr = iota(1,100).array;
foreach(ref i; parallel(arr)) {
    i = i*i;
}

La función parallel utiliza el operador opApply de forma interna. La función global parallel es una forma rápida de llamar a la función taskPool.parallel, que es un TaskPool (un grupo de hilos) que usa tantos hilos de ejecución como el número total de CPU menos uno. Crear una instancia propia permite controlar el grado de paralelismo.

Hay que tener cuidado de que el cuerpo de cada iteración pasada a parallel no modifique elementos a los que otra unidad de ejecución tenga acceso.

La función opcional workingUnitSize especifica el número de elementos procesados por cada hilo de ejecución.

La función reduce

La función std.algorithm.iteration.reduce, conocida en otros contextos de programación funcional como accumulate o foldl, llama a la función fun(acc, x) para cada elemento x donde acc es el resultado previo:

// 0 es la "semilla"
auto sum = reduce!"a + b"(0, elements);

La función Taskpool.reduce es la función análoga a reduce que usa paralelismo:

// Encuentra la suma de un rango en paralelo, usando el
// primer elemento de cada unidad de trabajo como semilla.
auto sum = taskPool.reduce!"a + b"(nums);

La función TaskPool.reduce divide el rango en subrangos que se reducen en paralelo. Una vez que los resultados han sido calculados, estos resultados son reducidos en sí mismos.

La función task()

La función task es un envoltorio para una función que podría tardar mucho tiempo en ejecutarse o que se debería ejecutar en su propio hilo. Incluso puede ser encolada en un grupo de tareas (taskpool):

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

O podría ser ejecutada directamente en un nuevo hilo de ejecución propio:

t.executeInNewThread();

Para obtener el resultado de una tarea se llama a la función yieldForce sobre ella. Esta función se bloquea hasta que el resultado está disponible.

auto fileData = t.yieldForce;

En profundidad

rdmd playground.d