2009-03-24 12 views
0

私は、個人の行動をシミュレートするFortranルーチンを並列化しました。ベクトル統計ライブラリ(数学カーネルライブラリのライブラリ)で乱数を生成すると、 。プログラムの構造は次のとおりです。スレッディング時のデータ破壊ベクトル統計ライブラリ - 数学カーネルライブラリ

program example 
... 
!$omp parallel do num_threads(proc) default(none) private(...) shared(...) 
do i=1,n 
call firstroutine(...) 
enddo 
!$omp end parallel do 
... 
end program example 

subroutine firstroutine 
... 
call secondroutine(...) 
... 
end subroutine 

subroutine secondroutine 
... 
VSL calls 
... 
end subroutine 

私は以下のように見えるメイクファイルとコンパイルにインテルFortranコンパイラを使用します。すべてが正常に動作し、コンパイル時に

f90comp = ifort 
libdir = /home 
mklpath = /opt/intel/mkl/10.0.5.025/lib/32/ 
mklinclude = /opt/intel/mkl/10.0.5.025/include/ 
exec: Example.o Firstroutine.o Secondroutine.o 
     $(f90comp) -O3 -fpscomp logicals -openmp -o aaa -L$(mklpath) -I$(mklinclude) Example.o -lmkl_ia32 -lguide -lpthread 
Example.o: $(libdir)Example.f90 
     $(f90comp) -O3 -fpscomp logicals -openmp -c $(libdir)Example.f90 
Firstroutine.o: $(libdir)Firstroutine.f90 
     $(f90comp) -O3 -fpscomp logicals -openmp -c $(libdir)Firstroutine.f90 
Secondroutine.o: $(libdir)Secondroutine.f90 
     $(f90comp) -O3 -fpscomp logicals -openmp -c -L$(mklpath) -I$(mklinclude) $(libdir)Secondroutine.f90 -lmkl_ia32 -lguide -lpthread 

。変数を生成するプログラムを実行すると、すべてうまくいくように見えます。しかし、時には(200-500反復ごとに1回)、数回の反復で狂った数が生成され、通常の方法で再び実行されます。私はこの腐敗がいつ起こるのかを知っていません。

なぜ起こっているのですか?

答えて

0

私は解決策を得ました!私はファイルから取ったいくつかの値によって生成された擬似乱数を修正していました。時々、複数のスレッドが同じファイルを読み込もうとしましたが、破損が発生しました。これを解決するために、私はompクリティカルセクションを追加しました。

0

乱数コードはグローバル変数を内部的に使用しているか、すべてのスレッドが同じジェネレータを使用しています。最終的には、2つのスレッドが同時に同じメモリを更新しようとしますが、結果は予測不可能になります。

スレッドごとに1つの乱数ジェネレータを割り当てる必要があります。

解決策:セマフォ/ロックを使用してランダムルーチンへの呼び出しを保護します。

+0

マスカーネルライブラリを使用するという考えは、スレッドセーフです。各スレッドは、同じグローバル変数にアクセスせずに乱数のストリームを生成します。 – Bellman

+0

私の編集を参照してください。乱数ジェネレータには、次の番号のパラメータを記憶する何らかの種類のメモリがあります。スレッドごとに1つのジェネレータを割り当てない場合、これは「グローバルストレージ」としてカウントされます。 –

関連する問題