- この記事では、標準の
std::lower_bound 関数より2倍高速で、より短い汎用二分探索の C++ 実装について論じています。
- 新しい実装は、分岐/条件付きジャンプではなく条件付き移動命令にコンパイルされるため、「ブランチレス」です。
- 二分探索は、ソート済みリストを中央の要素で2つに分け、中央の値を与えられた値と比較することで動作します。比較結果に応じて、どちらの部分リストを続けて探索するかを決定します。
- この記事では、分岐予測という概念についても論じています。これは、プロセッサが命令を並列実行して速度を高める技術です。しかし、二分探索は予測しにくいため、分岐予測は理想的ではありません。
- 著者は、標準実装や
branchless_lower_bound 版より高速な新しい二分探索実装 sb_lower_bound を紹介しています。これは、ループ内の命令数がはるかに少ないため高速です。
- 著者はまた、探索リストの分割に別の方法を使う、より高速な版
bb_lower_bound も提示しています。
- この記事は、プログラムの最も遅い部分がプロセッサにとって予測不能な探索や比較を含むなら、
clang を -mllvm -x86-cmov-converter=false とともに使ってみることを提案して締めくくられています。より高速な二分探索が必要なら、sb_lower_bound を試してみてください。
- 著者はまた、新しい二分探索実装のコードを提供し、それぞれの性能について詳しく論じています。
- この記事は、ホットループ内のアセンブリ命令数を9から8に減らした
sb_lower_bound のリファクタリング版で更新されており、これにより速度がわずかに向上しました。
- 著者はまた、プリフェッチという概念についても論じています。これは、特定のメモリ領域をキャッシュに先読みし、プリフェッチされたデータが実際に必要になったときに L1/L2 キャッシュ遅延だけが発生するようにするものです。256KB+ 向けにプリフェッチを追加した
sb_lower_bound 版も提供されています。
- この記事は Mihail Dumitrescu によって執筆され、2023年6月24日に公開されました.
1件のコメント
Hacker Newsの意見
lowerBoundを実装するために、“bare-metal” 言語へコンパイルされる Nim 言語の使用を提案しています。sb_lower_boundを使い、それ以外の場合はstd::lower_boundを使うことで達成できると提案しています。