Seasons.NET

ちょっとした技術ブログです

求む!!ハードウェア乱数生成

仕事で乱数を作成せねばならなくなり、
そのときは、鬼煮詰まっていたので、
フレームカウントを持ちいて加算したりして適当ルーチンくんだったが
さすが立て続けにコールしても精度が全然よくないわけで。

ネットでハードウェア乱数生成ルーチンなるものに
遭遇しましたが、us精度のタイマーを使って、
乱数生成時にファイルの作成->クローズの処理時間を使って、

乱数 = [処理前時間 ^ 処理後時間]

ってな感じで乱数を得ているプログラムでしたが、
組み込みにおいてそんなたいそうなこともできるわけもなく・・・
( 処理時間がかかりすぎる・・・ )

結局、
1.内蔵タイマーの精度を50usタイマーで作成
2.タイマー割り込み内でシードをインクリメント
3.乱数生成時にそのシードを使ってあれやこれやする
で作りましたが

実際使う時は、

val1 = get_random_range( 0,10 ); //=> 指定範囲の乱数を取得
val2 = get_random_range( 0,10 ); //=> 指定範囲の乱数を取得
な感じで立て続けに呼ぶので、
当然50usタイマー割り込みがかかるわけないので、、、
精度が宜しくない。
( 【備考】タイマー精度を余りにも小さくしすぎると
割り込みかかりすぎで処理落ちするので50us程度にしてます。 )

get_random_range()内でなんか適当に処理負荷が少しかかるようにして
シードが必ず変更するようにして、今、ある程度の乱数精度を得ていますが、
こんなんでいいのでしょうか?

あとは、CPUのレジスタのフラグとか、そのときのCPUレジスタの状態などを
シードに対して計算することで、ある程度ごまかすことも考えてますが、
当然その部分は、アセンブラでの記述になります。

今後CPUが変更になることも考えられるので、あまりCPU依存にしたくないと考えます。