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;