Menu

std.parallelism

Модуль std.parallelism реализует высокоуровневые примитивы для удобной организации параллельного программирования.

parallel

std.parallelism.parallel позволяет автоматически распределить тело цикла foreach между разными потоками:

// параллельно возвести в квадрат
// элементы arr
auto arr = iota(1,100).array;
foreach(ref i; parallel(arr)) {
    i = i*i;
}

Внутри parallel используется оператор opApply. Глобальная функция parallel - это упрощённый вариант вызова taskPool.parallel. Она применяет TaskPool, использующий количество рабочих потоков, равное общему числу процессоров - 1. Создание отдельного пула позволяет назначить степень параллелизма.

Обратите внимание, тело parallel-итерации не должно изменять элементы, к которым может иметь доступ другая рабочая единица.

Опциональный параметр workingUnitSize задаёт количество элементов, обрабатываемых каждым потоком.

reduce

Функция std.algorithm.iteration.reduce, известная в других функциональных контекстах как accumulate или foldl, вызывает функцию fun(acc, x) для каждого элемента x, передавая через acc предыдущий результат:

// 0 - начальное значение
auto sum = reduce!"a + b"(0, elements);

Taskpool.reduce - это параллельный аналог reduce:

// Вычислить сумму диапазона параллельно, используя
// первый элемент каждой рабочей единицы как начальное значение
auto sum = taskPool.reduce!"a + b"(nums);

TaskPool.reduce разделяет диапазон на поддиапазоны, которые обрабатываются параллельно. Как только результаты от отдельных поддиапазонов становятся известны, они так же обрабатываются.

task()

task - это обёртка для функции, исполнение которой может занять значительное время или которую следует исполнить в собственном рабочем потоке. Её можно поставить в очередь пула задач:

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

или же непосредственно исполнить в отдельном новом потоке:

t.executeInNewThread();

Чтобы получить результат задачи, необходимо вызвать yieldForce. Этот вызов блокирует текущий поток до тех пор, пока не будет получен результат.

auto fileData = t.yieldForce;

Подробнее

rdmd playground.d