# 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)