# Lazy SMP
Lazy SMP は、複数スレッドが同じルート局面をほぼ独立に探索しつつ、
共有[置換表](/shogi/shogiwiki/search/transposition-table/)を通じてゆるく協調する並列探索方式である。
実装のしやすさに対して実用上の効果が高く、現代エンジンで広く採用されている。
## 概要
Lazy SMP では、各スレッドが
- 同じ局面
- 似た深さ
- 少し違う手順や深さ設定
で探索を進める。
完全に仕事を厳密分担するのではなく、
どこかのスレッドが見つけた情報を共有[置換表](/shogi/shogiwiki/search/transposition-table/)へ書き込み、
他のスレッドがそれを利用することで全体として得をする。
## なぜ「lazy」なのか
この方式は、厳密な仕事分配や複雑な同期を避け、
「だいたい同じ探索を並列に走らせて、共有情報から自然に利益を得る」
という緩い協調を取る。
そのため、
- 実装が比較的簡単
- 複雑な並列 αβ より壊れにくい
- 実戦強度で十分なスケーリングが出やすい
という利点がある。
## Thread Voting
最近の実装では、各スレッドの最善手候補を集めて投票する
`thread voting` が使われることがある。
各スレッドの
- 深さ
- スコア
- 最善手
を見て、どの手を最終的なルート手として採用するかを決める。
## 実装イメージ
```cpp
void startHelpers(const Position& root, int depth, int alpha, int beta) {
for (Thread& th : helperThreads) {
th.root = root;
th.depth = depth + th.id % 2; // 少しだけ深さをずらす例
th.alpha = alpha;
th.beta = beta;
th.start();
}
}
```
実際には、
- 共有ハッシュ
- 停止フラグ
- ルート手の投票
- 反復深化との同期
を合わせて設計する。
## Stockfish との関係
Chessprogramming Wiki にもある通り、
Stockfish は 2016 年ごろに YBW 系から Lazy SMP へ移行したことで知られる。
GitHub 上の議論でも、
「スレッド数を増やすと同じ答えへ早く到達するというより、
同じ時間でより強い手を見つけやすくなる」
という性質が説明されている。
## 将棋AIでの位置づけ
将棋AIでも、
- 共有[置換表](/shogi/shogiwiki/search/transposition-table/)
- [NNUE](/shogi/shogiwiki/search/nnue/)評価
- [反復深化](/shogi/shogiwiki/search/iterative-deepening/)
を前提にした並列探索では、Lazy SMP 的な発想は非常に相性がよい。
ただし、スレッド数が増えると
- メモリ帯域
- ハッシュ競合
- NUMA
の影響も大きくなる。
## 注意点
- 厳密な仕事分割ではないので、理論上は重複探索が多い
- 時間短縮と棋力向上は同じではない
- 大規模マシンでは NUMA やメモリ帯域がボトルネックになりやすい
## 関連項目
- [並列探索](/shogi/shogiwiki/search/parallel-search/)
- [Young Brothers Wait Concept](/shogi/shogiwiki/search/young-brothers-wait-concept/)
- [置換表](/shogi/shogiwiki/search/transposition-table/)
- [反復深化](/shogi/shogiwiki/search/iterative-deepening/)
## 参考にしたホームページ
- [Chessprogramming Wiki: LAZY SMP](https://www.chessprogramming.org/Lazy_SMP)
- [Chessprogramming Wiki: Parallel Search](https://www.chessprogramming.org/Parallel_Search)
- [GitHub: official-stockfish/Stockfish](https://github.com/official-stockfish/Stockfish/issues/4035)
- [GitHub: official-stockfish/Stockfish](https://github.com/official-stockfish/Stockfish/issues/5253)