ナビゲーション:前へ 上へ 次へ
ナビゲーション:前へ 上へ 次へ
14 critical指示構文
共有データの更新を行う際に複数のスレッド間で競合が発生し、意図した結果が得られない場合があります。 critical指示構文を使うと他のスレッドと同時に実行されないことが保証される領域(クリティカルセクション等と呼ばれる)を指定することができます。以下に参考図を示します。
理解を深める上でcritical指示構文を用いる次のプログラムコードを考えます。
program exampleCritical implicit none integer,parameter :: N = 10 integer myTask, nextTask nextTask = 1 !$omp parallel private(mytask) do !$omp critical myTask = nextTask nextTask = nextTask + 1 !$omp end critical if ( myTask > N ) exit print *, "Processing task =", myTask end do !$omp end parallel print *, "Done..." endこのコードは各スレッドが用意されている仕事(task)を順番に処理していきますが、 仕事の割り当てを行う以下の部分は他のスレッドと同時に実行されては困る部分ですので、 critical指示構文でそれを防いでいます。
!$omp critical myTask = nextTask nextTask = nextTask + 1 !$omp end critical仮にcritical指示構文を使わなかった場合、 myTask = nextTaskの直後(そしてnextTask = nextTask + 1の処理が行われる前)に 他のスレッドがmyTask = nextTaskの処理を行ってしまい、同じ仕事が複数回行われてしまう可能性が出てきます。
14.1 ☆演習課題:critical指示構文
下記に示すプログラムは1から10000までの数値の合計を逐次計算と並列計算でそれぞれ求めてその結果を表示します。 しかしながらこのままでは(必ずしも)正しく動きません。 このコードにcritical指示構文を追加して正しく動くように書き換えて下さい。[課題のコード] program kadaiCritical implicit none integer,parameter :: N = 10000 integer i, totalParallel, totalSerial !逐次計算で合計を求める totalSerial = 0 do i=1, N totalSerial = totalSerial + i end do totalParallel = 0 !並列計算で合計を求める !$omp parallel !$omp do do i=1, N totalParallel = totalParallel + i end do !$omp end do !$omp end parallel print *, "Total(serial) :", totalSerial print *, "Total(parallel) :", totalParallel end program
[正しい実行結果の例] Total(serial) : 50005000 Total(parallel) : 50005000解答例:kadaiCritical.f90
ナビゲーション:前へ 上へ 次へ