モジュールstd.parallelism
は便利な並行プログラミングのための高いレベルのプリミティブを実装します。
std.parallelism.parallel
はforeach
本文を自動的に異なるスレッドに分配します:
// 並列にarrを二乗
auto arr = iota(1,100).array;
foreach(ref i; parallel(arr)) {
i = i*i;
}
parallel
は内部でopApply
オペレータを使用します。
グローバルのparallel
はCPUの合計数 - 1のワーキングスレッドを使うTaskPool
である
taskPool.parallel
へのショートカットです。
自分独自のインスタンスを作ると並列度をコントロールできます。
parallel
な反復処理の本文は別のワーキングユニットがアクセスするかもしれない要素にアクセスしないことが
確実でなければならないことを覚えておいてください。
任意のworkingUnitSize
はワーカースレッドあたり処理される要素の数を決めます。
関数
std.algorithm.iteration.reduce
は、
他の関数型の文脈ではaccumulateまたはfoldlとして知られるもので、
各要素x
で関数fun(acc, x)
を呼びます。ここでacc
は前の結果です:
// 0は"シード"です
auto sum = reduce!"a + b"(0, elements);
Taskpool.reduce
はreduce
と似たものです:
// 各ワークユニットのシードとして最初の要素を使い、
// レンジの合計を並列に求めます。
auto sum = taskPool.reduce!"a + b"(nums);
TaskPool.reduce
はレンジを並列にreduceされるサブレンジに分割します。
それらの結果が計算されると、その結果をreduceします。
task()
task
は時間が長くかかったり、専用のワーキングスレッドで実行されるべき関数のラッパーです。
それはタスクプールのキューに追加されるか:
auto t = task!read("foo.txt");
taskPool.put(t);
または直接専用の新しいスレッドで実行されます:
t.executeInNewThread();
タスクの結果を得るにはyieldForce
を呼びます。
それは結果が取得できるようになるまでブロックします。
auto fileData = t.yieldForce;