分岐予測とホットループ
CPUの分岐予測を助け、コンパイラーが最適化しやすいループを記述します。
「分岐予測とホットループ」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
分岐予測器
現代のCPUは、現在の命令が完了する前に次の命令を予測します。予測を誤るとパイプラインが停止し、10〜20サイクルのコストが発生します。
予測しやすい分岐
ほとんど常に一方へ分岐するものや、明確なパターンに従う分岐は正確に予測されます。ランダムな分岐は性能に壊滅的な影響を与えます。
ソート済みデータの効果
条件分岐を含むソート済みデータの反復処理は、ソートされていないデータより高速になることがよくあります。分岐予測器がパターンを学習できるためです。
// Often much faster on sorted data
std::sort(v.begin(), v.end());
int sum = 0;
for (int x : v) {
if (x > 128) sum += x;
}分岐なしコード
可能な場合は、分岐を算術演算に置き換えます。CPUが両方の経路を評価し、分岐なしで選択できるためです。
// Branchy
int max(int a, int b) { return (a > b) ? a : b; }
// Branchless (often equivalent in machine code)
int max(int a, int b) { return a + (b - a) * (b > a); }より適した選択肢としてのstd::max
現代のコンパイラーは、分岐なしコードを自動的に生成することがよくあります。コードは分かりやすく書き、最適化処理を任せてください。ただし、ホットパスでは逆アセンブル結果を確認します。
likelyとunlikelyのヒント
C++20では、コンパイラーにヒントを与える[[likely]]と[[unlikely]]が追加されました。
if (error_condition) [[unlikely]] {
handle_error();
}ループアンローリング
反復ごとの処理量を増やすと、分岐の頻度を減らせます。現代のコンパイラーは自動的にアンロールするため、#pragma unrollは効果を測定してから使ってください。
ループ内で異なる処理を混在させない
2つのケースがランダムに交互に現れるループでは、分岐予測が機能しません。可能であれば、ケースごとに1つずつ、2つのループに分けます。
// Slow: random switching
for (auto& x : v) {
if (x.type == A) process_A(x);
else process_B(x);
}
// Faster: partition first
std::partition(v.begin(), v.end(), [](auto& x) { return x.type == A; });
for (size_t i = 0; i < boundary; ++i) process_A(v[i]);
for (size_t i = boundary; i < v.size(); ++i) process_B(v[i]);ホットな関数をインライン化する
ホットループでは、関数呼び出しのオーバーヘッドが関数本体の処理量に匹敵することがあります。inlineヒントが役立ちます。__attribute__((always_inline))(GCC/Clang)はさらに強制力の強い指定です。
直感を信じない
コンパイラーとCPUは非常に賢いものです。最適化の前に測定してください。「明らかに」分岐のないバージョンでも、分岐予測器が学習した後は、分岐を使うバージョンより遅いことがあります。
幅広いループにSIMDを使う
自動ベクトル化により、可能な場合はループがSIMD命令に変換されます。コードを簡潔にし、単純な型を使い、反復間のデータ依存を避けてください。
プロファイル誘導最適化(PGO)
コンパイルし、実行してプロファイルデータを収集し、ヒントを付けて再コンパイルします。コンパイラーはそのデータを使って、どの分岐がホットになるかをより正確に予測します。
理解度チェック
フィルタリングループの前にデータをソートすると、実行が高速化することがあるのはなぜですか。
まとめ
分岐予測の失敗にはサイクルのコストがかかります。分岐を予測しやすく保ち(ソート済みデータが役立ちます)、likely/unlikelyヒントを使い、ループを均一に保つために処理を分割してください。プロファイリングで反証されない限り、コンパイラーの最適化を信頼します。
よくある質問
「分岐予測とホットループ」レッスンは無料ですか?
はい。「分岐予測とホットループ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「分岐予測とホットループ」で何を学びますか?
CPUの分岐予測を助け、コンパイラーが最適化しやすいループを記述します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「分岐予測とホットループ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。