O módulo std.parallelism
implementa
primitivas de alto nível para uma programação simultânea conveniente.
std.parallelism.parallel
permite distribuir automaticamente
o corpo de um foreach
para diferentes threads:
// raíz quadrada em paralelo
// dos elementos arr
auto arr = iota(1,100).array;
foreach(ref i; parallel(arr)) {
i = i*i;
}
parallel
utiliza internamente o operador opApply
.
parallel
global é um atalho para o taskPool.parallel
que é um TaskPool
que usa número total de cpus - 1
de working threads. Criar sua própria instância permite
controlar o grau de paralelismo.
Observe que o corpo de uma iteração parallel
deve
garantir que não modifique itens aos quais outra
unidade de trabalho possa ter acesso.
O workingUnitSize
opcional especifica o número de elementos processados
por worker thread.
A função
std.algorithm.iteration.reduce
-
conhecida em outros contextos funcionais como accumulate ou foldl -
chama uma função fun(acc, x)
para cada elemento x
em que acc
é o resultado anterior:
// 0 é a "semente"
auto sum = reduce!"a + b"(0, elements);
Taskpool.reduce
é o análogo paralelo do reduce
:
// Encontre a soma de um range em paralelo, usando o primeiro
// elemento de cada unidade de trabalho como semente.
auto sum = taskPool.reduce!"a + b"(nums);
O TaskPool.reduce
divide o range em
sub-ranges que são reduzidos em paralelo. Depois que esses
resultados tiverem sido calculados, os resultados serão reduzidos
por si mesmos.
task()
task
é um wrapper para uma função
que pode demorar mais ou que deve ser executada em
sua própria worker thread. Ela pode ser enfileirada
em um taskpool:
auto t = task!read("foo.txt");
taskPool.put(t);
Ou ser executado diretamente em sua própria e nova thread:
t.executeInNewThread();
Para obter o resultado de uma task, chame yieldForce
sobre ela. Ela será bloqueada até que o resultado esteja disponível.
auto fileData = t.yieldForce;