Skip to content

Commit

Permalink
MSB64 を使うことで香車の効きの最適化 (yaneurao#272)
Browse files Browse the repository at this point in the history
* Optimize black lance effect using MSB64

* Support perft by bench command

* Optimize Bitboard::decrement with alignr
  • Loading branch information
grafi-tt authored and nodchip committed Apr 12, 2024
1 parent b3e84e0 commit 6b4cdca
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 30 deletions.
21 changes: 11 additions & 10 deletions source/bitboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void Bitboards::init()
for (Rank r = RANK_1; r <= RANK_9; ++r) {

Bitboard left(ZERO), right(ZERO);

// SQの升から左方向
for (File f2 = (File)(f + 1); f2 <= FILE_9; ++f2)
left |= Bitboard(f2 | r);
Expand Down Expand Up @@ -584,19 +584,20 @@ Bitboard Bitboard::decrement() const
{
#if defined(USE_SSE2)

#if defined(USE_SSE41)
// _mm_setzero_si128()は同一レジスタのXORとなる。
// 同一レジスタのXORは依存性が切れる
// SandyBridge以降Skylake系までなら実行ユニットも使用しない
__m128i t2 = _mm_cmpeq_epi64(m, _mm_setzero_si128());
// alignrを使ってcmpeqの結果(p[0] == 0 ? -1 : 0)を上位64bit側にシフトしつつ、下位を-1で埋める
t2 = _mm_alignr_epi8(t2, _mm_set1_epi64x(-1LL), 8);
__m128i t1 = _mm_add_epi64(m, t2);
#else // SSE2用のコード
// p[0]--;
__m128i c = _mm_set_epi64x(0, 1);
__m128i t1 = _mm_sub_epi64(m, c);

// if (p[0] MSB == 1) p[1]++;
#if defined(USE_SSE41)
__m128i t2 = _mm_cmpeq_epi64(m, _mm_setzero_si128());
//_mm_setzero_si128()は同一レジスタのXORとなる。
//同一レジスタのXORは依存性が切れる
//SandyBridge以降Skylake系までなら実行ユニットも使用しない
t2 = _mm_slli_si128(t2, 8);
t1 = _mm_add_epi64(t1, t2);
#else // SSE2用のコード
// if (p[0] MSB == 1) p[1]--;
__m128i t2 = _mm_srli_epi64(t1, 63); // MSBをbit0に持ってきて、byte shiftで上位64bit側に移動させて減算
t2 = _mm_slli_si128(t2, 8);
t1 = _mm_sub_epi64(t1, t2);
Expand Down
29 changes: 9 additions & 20 deletions source/bitboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -912,21 +912,16 @@ inline Bitboard lanceEffect(Square sq, const Bitboard& occupied)
// 香がp[0]に属する
u64 se = lanceStepEffect<C>(sq).template extract64<0>();
u64 mocc = se & occupied.extract64<0>();
mocc |= mocc >> 1;
mocc |= mocc >> 2;
mocc |= mocc >> 4;
mocc >>= 1;
return Bitboard(~mocc & se, 0);
// 香が当たる駒より上の升に対応するビットを0、それ以外を1にする
mocc = ~uint64_t{0} << MSB64(mocc | 1);
return Bitboard(mocc & se, 0);
}
else {
// 香がp[1]に属する
u64 se = lanceStepEffect<C>(sq).template extract64<1>();
u64 mocc = se & occupied.extract64<1>();
mocc |= mocc >> 1;
mocc |= mocc >> 2;
mocc |= mocc >> 4;
mocc >>= 1;
return Bitboard(0, ~mocc & se);
mocc = ~uint64_t{0} << MSB64(mocc | 1);
return Bitboard(0, mocc & se);
}
}
#endif
Expand Down Expand Up @@ -956,13 +951,10 @@ inline Bitboard rookFileEffect(Square sq, const Bitboard& occupied)
// 先手の香の利き
u64 se = lanceStepEffect<BLACK>(sq).template extract64<0>();
u64 mocc = se & occupied.extract64<0>();
mocc |= mocc >> 1;
mocc |= mocc >> 2;
mocc |= mocc >> 4;
mocc >>= 1;
mocc = ~uint64_t{0} << MSB64(mocc | 1);

// 後手の香の利きと先手の香の利きを合成
return Bitboard(((em ^ t) & mask) | (~mocc & se), 0);
return Bitboard(((em ^ t) & mask) | (mocc & se), 0);
}
else {
// 飛車がp[1]に属する
Expand All @@ -974,12 +966,9 @@ inline Bitboard rookFileEffect(Square sq, const Bitboard& occupied)

u64 se = lanceStepEffect<BLACK>(sq).template extract64<1>();
u64 mocc = se & occupied.extract64<1>();
mocc |= mocc >> 1;
mocc |= mocc >> 2;
mocc |= mocc >> 4;
mocc >>= 1;
mocc = ~uint64_t{0} << MSB64(mocc | 1);

return Bitboard(0, ((em ^ t) & mask) | (~mocc & se));
return Bitboard(0, ((em ^ t) & mask) | (mocc & se));
}
}

Expand Down
3 changes: 3 additions & 0 deletions source/testcmd/benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ void bench_cmd(Position& current, istringstream& is)
else if (limitType == "mate")
limits.mate = stoi(limit);

else if (limitType == "perft")
limits.perft = stoi(limit);

else
// depth limit
limits.depth = stoi(limit);
Expand Down

0 comments on commit 6b4cdca

Please sign in to comment.