SIMD-oriented Fast Mersenne TwisterのQ and A

English

ソースコードについて

マスクの上位ビットは無効だから、0にしていいですか?
質問: 符号なし整数をサポートしていない言語への移植を考えています。 do_recursion 関数の中に、
(b->u[0] >> SR1) & MSK1
という部分があるけど、右シフトによって u[0]の上位SR1ビットは0にセットされるので、 マスクの方も上位ビットは 0 でいいですか?
答え: そのとおり、MSKの上位ビットは無効です。 したがって、0にしても構いません。 なお、念のため、移植した時は、出力列が同一かチェックするようにお願いします。
Visual C++ でコンパイルすると遅い。
質問:SFMTは速いというが、Visual C++でコンパイルして 実行速度を計測したら速くない。
答え: do_recursion, mm_recursion がインライン展開されていないという 可能性があります。これらの関数はループの中から呼ばれるので、 インライン展開されないと、全体の速度を落とします。 do_recursion, mm_recursion のインライン指定に __inline の代わりに、__forceinline を指定することができるという情報があります。 (VC++ 6.0以降) また、mm_recursion をマクロに書き直すという方法もあります。 ただし、この結果として、コンパイラのインライン関数の制限などによって、SSE2 操作系の 関数 _mm_xxx がインライン展開されなくなるかも知れません。この場合は、劇的に 遅くなります。コンパイラオプションなどを調整して、より多くの関数がインライン展開 されるようにする必要があります。なお、私たちはVC++を使用していないので、 この項目の情報は直接確認したものではありません。

dSFMT と MinGW について

dSFMT ver. 1.3 は MinGW で動かない。(cygwinでも)
答え: cygwinについてレポートあり。 そして Yusdi Santoso さんが、MinGWでこれを避ける方法をメールしてくれました。
I found out that this was due to stack misalignment. Instead of aligning the __m128i variables at 16bytes boundary, the compiler aligned them with 8 bytes offset. In any case I found that I can work this around by commenting one line in dSFMT.c:
	  /** dsfmt initialized flag */
	  //int dsfmt_global_is_initialized = 0;                  //this line is commented
	
Instead I add this line in the file that contain the main function. In your example, inside test.c. This hack somehow make the alignment normal again.
cygwin にこの方法が通用するかどうかはまだ試していません。
答え: dSFMT ver. 2.0 は cygwin で動作します。 (たぶん、MinGWでも)これは、単に dsfmt_global_is_initialized に よる初期化済みチェックを外しただけなので、(cygwin, MinGW以外でも) 使うときはちゃんと初期化してから使って下さい。

SFMTのメインページに戻る