マンデルブロ集合を計算するプログラムの中でバッファに判定結果をセットするcalc()を疑似乱数を埋め込むルーチンに差し替えてみました。256×256のセルをクリアした後xrand()で発生させた0~255の乱数列の2個づつをx,yとし、指定されたセルをインクリメントさせる操作を256*256*256=16,777,216回繰り返します
乱数の統計的な評価方法はいろいろありますがデータを画像にしてぱっと見で比べてみます。もしxrand()で一様な乱数が発生すると256×256の全てのセルが256近くまでカウントアップして画像で見るとムラの無い一様な色で見えるはずです
xrand()の中身は以下でとっかえひっかえし、こういう使い方をしてはいけない。といわれる隣接する2個づつを組とするベクタ(ai,ai+1)で取り出しています
①線形合同法:次の漸化式で高速に計算できます。よく使われる「1103515245」という定数にどういう意味があってどこから持ってきたのか由来が不祥らしいですがLSIC-86の組込み関数rand()はまんまこの式でした。
②GCCの組込み関数rand():実装がどうなっているかソースを追ってみたのですがよくわかりませんでした
③GCCの組込み関数random():rand()より質の良い乱数を発生するとなっていますがどうでしょうか
④メルセンヌツイスターgenrand_int31():ライブラリのソースは手直し無しでそのままGCCでコンパイル通りました
結果:
①線形合同法 実行時間31秒 ②rand() 実行時間66秒
③random() 実行時間36秒 ④メルセンヌツイスター 実行時間59秒
①はやはり一様性に難がありそうです。画像の中央あたりにぼんやり赤いムラが見えます
②③はほとんど同じです。エイリアスで同じルーチンを呼び出してるのかもしれません。また画像に縦方向の筋がなんとなく見えて周期性が出てしまってるようです
④はさすがに一様でムラが無いように見えます。実行時間も十分高速です