[解決済み] ループのアンロールが役に立つとしたら、どんなときか?
2023-01-06 11:41:02
質問
私はいくつかの非常にパフォーマンスが重要なコード (モンテカルロ シミュレーション内で何百万回と呼び出されるクイック ソート アルゴリズム) をループ展開によって最適化しようとしています。 私が高速化しようとしている内部ループは次のとおりです。
// Search for elements to swap.
while(myArray[++index1] < pivot) {}
while(pivot < myArray[--index2]) {}
みたいな感じでアンロールしてみました。
while(true) {
if(myArray[++index1] < pivot) break;
if(myArray[++index1] < pivot) break;
// More unrolling
}
while(true) {
if(pivot < myArray[--index2]) break;
if(pivot < myArray[--index2]) break;
// More unrolling
}
これでは全く変化がないので、より読みやすい形に戻しました。 ループの展開を試した他のときにも、同じような経験があります。 最近のハードウェアの分岐予測の品質を考えると、ループ展開がまだ有用な最適化であるとすれば、それはいつなのでしょうか?
どのように解決するのですか?
ループのアンロールは、依存関係の連鎖を断ち切ることができれば意味があります。これは、アウトオブオーダーまたはスーパースカラー CPU に、物事をよりよくスケジュールする可能性を与え、その結果より速く実行できるようにします。
簡単な例です。
for (int i=0; i<n; i++)
{
sum += data[i];
}
ここでは、引数の依存関係は非常に短いです。データ配列のキャッシュミスのためにストールした場合、CPUは何もできず、ただ待つだけです。
一方、このコードでは
for (int i=0; i<n; i+=4)
{
sum1 += data[i+0];
sum2 += data[i+1];
sum3 += data[i+2];
sum4 += data[i+3];
}
sum = sum1 + sum2 + sum3 + sum4;
はより速く実行できるかもしれません。もし、ある計算でキャッシュミスやその他のストールが発生しても、ストールに依存しない他の3つの依存関係チェーンが残っています。順不同の CPU はこれらを実行することができます。
関連
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] INNER JOINよりもCROSS APPLYを使用すべきなのはどのような場合ですか?
-
[解決済み] 8192個の要素にループをかけると、プログラムが遅くなるのはなぜですか?
-
[解決済み] 例外を発生させるタイミングは?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】再帰はループより速いことがあるのか?
-
[解決済み] forループの中で<と<=のどちらを使うべきか [閉じた状態].
-
[解決済み] CUDAカーネルのグリッドとブロックの寸法はどのように選択するのですか?
-
[解決済み] translateZ(0)に対するCSSのパフォーマンス
-
[解決済み] なぜ私のアプリケーションは動作時間の24%をNULLチェックに費やすのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 最後の手段としてのパフォーマンス最適化戦略【終了しました
-
[解決済み] forループの中で<と<=のどちらを使うべきか [閉じた状態].
-
[解決済み] CUDAカーネルのグリッドとブロックの寸法はどのように選択するのですか?
-
[解決済み] Scalaのパターンマッチはバイトコードレベルでどのように実装されているのですか?
-
[解決済み] ファイルキャッシュをクリアしてパフォーマンステストを繰り返す
-
[解決済み] OFFSET / FETCH NEXTからの総行数取得
-
[解決済み] なぜSSEスカラーsqrt(x)はrsqrt(x) * xより遅いのですか?
-
[解決済み] Entity Frameworkのクエリは遅いが、SqlQueryの同じSQLは速い。
-
[解決済み] translateZ(0)に対するCSSのパフォーマンス
-
[解決済み] RustのOption型のオーバーヘッドとは?