Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSB64 を使うことで香車の効きの最適化 #272

Merged
merged 3 commits into from
Mar 18, 2024

Conversation

grafi-tt
Copy link
Contributor

ビットボードの実装を眺めていて、少し最適化を試してみました。

メインの変更は一つ目のコミットで、perft を試してみて Linux / CPU Zen2 / Compiler clang18 の環境で 7% くらい高速化しました。先手の香車の効きを求めるところで、1 を下位ビット側にビットシフト複数回で伝搬させる代わりに、MSB64 を使って最上位に立っている 1 の場所を求める実装としました。

こういう処理は本質的に x86 における bsr や lzcnt 命令を使うか、ビットシフトを log(bitwidth) 回行う必要があるはずです。Zen4 より前では では bsr のコストが高いという理由からか、lzcnt 命令にコンパイルされるようでした。命令数としては bsr の方が得にはなるのでコンパイラオプションとして -mno-lzcnt つけるとか、処理をいじって lzcnt 向けに最適化するとかやってみたのですが、速くなる感じはなかったので、コードのシンプルさなども考えて今の比較的わかりやすい書き方にしました。

AgnerFog https://www.agner.org/optimize/instruction_tables.pdf を見る限り AMD 系だと lzcnt のレイテンシが 1 で、Intel 系だと 3 のようなので、Intel 系では僅かにしか速くなっていないとは思います。

具体的には

// old
mocc |= mocc >> 1;
mocc |= mocc >> 2;
mocc |= mocc >> 4;
mocc >>= 1;

// new
// `MSB64(x`) is `lzcnt(x) ^ 63` or `bsr(x)`
mocc = ~uint64_t{0} << MSB64(mocc | 1);

の比較ということになりますが、前者のレイテンシは 7 cycles で、後者のレイテンシは Intel だと lzcnt で 6 cycles、bsr で 5 cycles となります。

また、128bit のデクリメントの最適化もやってみました。さらに unpack をなくしてみるのも試したのですが、やっぱり unpack した状態でデクリメントする現状の実装のほうが速そうなので諦めました。

@yaneurao
Copy link
Owner

プルリクありがとうございます。素晴らしいです!

当該部分の香の利きのコード、私は書いてる時は「このあと55将棋と56将棋の対応コード書かないといけないから、わかりやすいコードにしよう…」と思って詰めきれてませんでした。

@yaneurao yaneurao merged commit 26deea8 into yaneurao:master Mar 18, 2024
184 of 192 checks passed
nodchip pushed a commit to nodchip/tanuki- that referenced this pull request May 5, 2024
* Optimize black lance effect using MSB64

* Support perft by bench command

* Optimize Bitboard::decrement with alignr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants