2012/09/29
■ 手生成ベンチマーク
ベンチマークができる程度になってきたので色々測ってみた。上記の後手番での手生成回数。
コンパイラ別
CPU:phenom II 3.2GHz
OS | コンパイラ | SIMD命令 | 回数 |
---|---|---|---|
windows XP 32bit | mingw 4.7 | 無 | 1174398 |
windows XP 32bit | mingw 4.7 | 有 | 876808 |
ubuntu 64bit | gcc 4.6 | 無 | 1391788 |
ubuntu 64bit | gcc 4.6 | 有 | 1036269 |
ubuntu 64bit | icc 12.0 | 無 | 1388889 |
ubuntu 64bit | icc 12.0 | 有 | 1251564 |
ubuntu 64bit | icc 13.0 | 無 | 1323627 |
ubuntu 64bit | icc 13.0 | 有 | 1104972 |
ubuntu 64bit | clang 3.0 | 無 | 1158078 |
ubuntu 64bit | clang 3.0 | 有 | 1044932 |
ubuntu 32bit | gcc 4.6 | 無 | 1123596 |
ubuntu 32bit | gcc 4.6 | 有 | 883783 |
ubuntu 32bit | icc 12.0 | 無 | 1184834 |
ubuntu 32bit | icc 12.0 | 有 | 1201923 |
ubuntu 32bit | icc 13.0 | 無 | 1187648 |
ubuntu 32bit | icc 13.0 | 有 | 1178550 |
CPU別(コンパイラ gcc 4.6,4.7)
CPU | OS | SIMD命令 | 回数 |
---|---|---|---|
prescott pen4 2.8GHz | ubuntu 64bit | 無 | 622665 |
prescott pen4 2.8GHz | ubuntu 64bit | 有 | 342583 |
phenom II 3.2GHz | ubuntu 64bit | 無 | 1391788 |
phenom II 3.2GHz | ubuntu 64bit | 有 | 1036269 |
northwood pen4 3.0GHz | debian 32bit | 無 | 735565 |
northwood pen4 3.0GHz | debian 32bit | 有 | 632711 |
prescott pen4 3.2GHz | debian 32bit | 無 | 683761 |
prescott pen4 3.2GHz | debian 32bit | 有 | 328569 |
conroe core2 2.4GHz | ubuntu 64bit | 無 | 984252 |
conroe core2 2.4GHz | ubuntu 64bit | 有 | 834376 |
core i3 3.4GHz | ubuntu 64bit | 無 | 2100840 |
core i3 3.4GHz | ubuntu 64bit | 有 | 1315790 |
SIMD命令はまだうまく書けて無いようなので、参考までに。実はconroeを測定したときに古くて遅いCPUなのに、結構いいスコアをたたき出したので、急遽core i3を買ってきた次第。bfs/brs命令がAMDは遅いためbitboardでは不利と見た。
2012/09/22
■ bitboardによる手生成の実装方法
bitboardによる銀の移動手のコード例としては、
org=p->bitboard[BLACK][P_GIN]; // 先手の銀のbitboard while ( test128(org) ) { // 駒がある from=bit_pop1st(&org); // 駒位置 and128(t,attack_gin_b[from],target); // 先手銀の利きのbitboardを押し付ける while ( test128(t) ) { // 利きのある数 to=bit_pop1st(&t); // 移動先の位置 pin_check() 手の格納 } }
というふうになるであろう。上記コードにおいて、test128()はbitboardがゼロか非ゼロかをテストする関数である。
bit_pop1stはbitboardのLSBから立っているビット位置を返し、そのビットをクリアする関数である。32ビット版では次のようなコードとなっている。
bit_pop1st(BITBOARD *x) { int pos; if ( x->l ) { pos=__builtin_ctz(x->l); x->l&=(x->l-1); // reset bit return pos; } else if ( x->m ) { pos=__builtin_ctz(x->m)+32; x->m&=(x->m-1); // reset bit return pos; } pos=__builtin_ctz(x->h)+64; x->h&=(x->h-1); // reset bit return pos; }
_builtin_ctzはLSB側から'1'のビット位置を返す関数。x86ではbsf命令で展開される。
2012/09/09
■ 駒を取らない移動手王手の生成
静止探索内では駒を取る手、駒を取らない王手を生成している。
bitboardによる隣接王手生成
たとえば52に王がいるとして銀の利きデータを貼り付ける 9 8 7 6 5 4 3 2 1 0 0 0 1 0 1 0 0 0 一 0 0 0 0 K 0 0 0 0 二 0 0 0 1 1 1 0 0 0 三 0 0 0 0 0 0 0 0 0 四 0 0 0 0 0 0 0 0 0 五 0 0 0 0 0 0 0 0 0 六 0 0 0 0 0 0 0 0 0 七 0 0 0 0 0 0 0 0 0 八 0 0 0 0 0 0 0 0 0 九
ビットの立った位置に銀の利きがあれば王手となる
74に地点に銀がいるとして、銀の利きは
9 8 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 0 一 0 0 0 0 K 0 0 0 0 二 0 1 1 1 0 0 0 0 0 三 0 0 S 0 0 0 0 0 0 四 0 1 0 1 0 0 0 0 0 五 0 0 0 0 0 0 0 0 0 六 0 0 0 0 0 0 0 0 0 七 0 0 0 0 0 0 0 0 0 八 0 0 0 0 0 0 0 0 0 九
上記のbitboardに銀の利きをandして
9 8 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 0 一 0 0 0 0 K 0 0 0 0 二 0 0 0 1 0 0 0 0 0 三 0 0 S 0 0 0 0 0 0 四 0 0 0 0 0 0 0 0 0 五 0 0 0 0 0 0 0 0 0 六 0 0 0 0 0 0 0 0 0 七 0 0 0 0 0 0 0 0 0 八 0 0 0 0 0 0 0 0 0 九
63の地点が王手の手となる