2011/03/30
■ 探索時間管理の設計(その2)
1手の思考時間を 残り時間/max((200-手数)/2,20) とする。(1局最大200手あるいは残り20手と仮定)
・浅く読む〜さっさと指す(Iteration打ち切り条件) スコアが勝ちに達したとき Iteration >= 6 でスコアが負けに達したとき Iteration >= 8 で最善手の探索ノード数が全ノードの85%で探索時間が1手時間の1/16か, 探索ノード数が全ノードの98%で探索時間が1手時間の1/32 ・深く読む Iteration >= 2 で前回のIterationでの最善手スコアより歩1/4枚分スコアが下がったときパニックモードとし、 序盤では1手の思考時間の2倍 中盤では1手の思考時間の3倍 終盤では1手の思考時間の4倍とする。
さっさと指すのはまだ工夫の余地あり。
2011/03/21
■ コンパイラ比較(その3)
3/14にgcc 4.6がstableとなっていたので、早速ベンチマーク。
いわゆる飛底の香の問題。
類型にYahoo!インターネット検定 - 将棋段級位認定試験もある。
上記の問題を検討モード(最長3分)で実行。Iteration=8終了のときの結果である。
CPU:AMD PhenomII X2 BE555 (3.9GHz)
コンパイラ | 総思考時間 | NPS | コンパイラオプション |
---|---|---|---|
VC2008 (WindowsXP32bit) | 7.8 | 260187 | /Ox /Ob2 /Oi /Ot /GL /GF /FD /EHsc /MD /Gy /arch:SSE2 /fp:fast /TC |
MinGW 4.5.2 (WindowsXP32bit) | 7.5 | 264521 | -O3 -march=amdfam10 -msse4a -mfpmath=sse-fno-exceptions -fomit-frame-pointer -fstrict-aliasing |
icc 12.0 (Ubuntu64bit) | 6.7 | 296948 | -O3 -ipo -no-prec-div -unroll -fno-alias -axSSE4.1 |
icc 12.0 (Ubuntu32bit) | 9.8 | 201170 | -O3 -ipo -no-prec-div -unroll -fno-alias -axSSE4.1 |
gcc 4.5.1 (Ubuntu64bit) | 7.0 | 283887 | -O3 -march=amdfam10 -msse4a -mfpmath=sse-fno-exceptions -fomit-frame-pointer -fstrict-aliasing |
gcc 4.5.1 (Ubuntu32bit) | 10.0 | 198811 | -O3 -march=amdfam10 -msse4a -mfpmath=sse-fno-exceptions -fomit-frame-pointer -fstrict-aliasing |
gcc 4.6.0 (Debian64bit) | 6.7 | 299347 | -O3 -march=amdfam10 -msse4a -mfpmath=sse-fno-exceptions -fomit-frame-pointer -fstrict-aliasing |
open64 4.2.4 (Ubuntu64bit) | 6.9 | 287973 | -Ofast -ipa -mtune=barcelona |
open64 4.2.4 (Ubuntu32bit) | 9.3 | 213400 | -Ofast -ipa -mtune=barcelona |
前回のプログラムでは手のオーダリングにバグがあったためコンパイラによりノード数に違いがあったが、今回はピタリ同じ。(ノード数:563298、静止探索ノード数:437123)
gcc4.6は素晴らしいが、unstableやexperimentalからのインストールなので、少々不安。ここを見るとLLVM/Clangも熱いですな。
2011/03/04
■ ランダム定跡の工夫
自動対戦で、同一対局を避けるために定跡を乱数化しているが、
srandでシードを設定した後、同じ乱数列が生成されるので、進行が同一となり面白くない。
そこで、rdtscを使い定跡を散らすことにする。
unsigned int my_rand() { #ifdef _MSC_VER return (unsigned int)__rdtsc(); #else #if defined(__i386) || defined(__x86_64) // x86なら unsigned int eax, edx; __asm__ volatile("rdtsc" : "=a"(eax), "=d"(edx)); return eax; // 下の32bitだけを返す #else return rand(); // x86以外ならrandを使いましょう #endif #endif }
'11/04/08 修正: 条件マクロのバグにより64bitで動かなかった