###初めに
大学のセミナーにてtask_reduction, in_reduction について調べることになったのですが、その時に日本語でこのテーマを解説しているサイトが見当たらず、テーマを理解するのに苦労しました。
もし今後自分と同様にこのテーマを初めて扱う初心者が居たら…といった感じで自分が分かった事を 初心者なりに可能な限り分かりやすくまとめてみます。 もし「ここは間違ってるよ」、「こういった説明の方が分かりやすいよ」といった場所があればご指摘していただけるとありがたいです。
###予備知識:Taskとは
OpenMPではWhileや、再帰的なアルゴリズムをTask関数によって、並列処理することが出来る。
omp pragma parallel とは違い、Taskでは、並列に行いたい処理を1つのタスクとして、タスクプールに貯蔵する。
貯蔵されたタスクは、後ほど空いているThreadが1つ1つ筒処理していく。
###予備知識:Task関数での関数
task タスクを作り出す
taskloop for文などをタスクで処理する
taskwait 当taskが作り出した子タスクが終了するまで待つ
taskgroup 作り出された子タスク及び孫タスク(子タスクの子タスク)がすべて終了するまで待つ
###task_reduction,in_reductionについて
task_reduction はtaskgroup に使うことが出来る
これによって、taskgroup内で作られるタスクはリダクションに参加する準備がされる
in_reduction はtask, taskloop, target(ここは自分が理解できていないので触れません) に使うことが出来る
in_reductionが使われたtaskは、タスクの処理後にリダクションに参加する
task_reduction,in_reductionで使う(reduction-identifier:list)はreductionと同じ
reduction はtaskloopに使うことが出来て、その場合はtask_reductionがtaskgroup に使われて、in_reduction はtaskに使われた時と同じ効果を発揮する
###task_reduction,in_reductionを使った例
一見task_reduction,in_reductionの仕組みが理解しにくかったので、例を置いてみる
以下のコードは、配列の偶数の位置にいる数字を足し合わせる
taskによって、色々なタスクがタスクプール内に積み込まれて、それぞれがThreadによって処理されていく
全ての処理が終わった後、 in_reduction が指定されたタスクのみがリダクションに参加する。
firstprivateのついたタスクではsum変数はプライベート変数なので、リダクションには影響を与えない
もし、firstprivateやin_reductionを使わなかった場合は、sum変数は共用となり、競合状態となってしまう…。
なので、in_reductionが必要とされる。