ホームページ >バックエンド開発 >C++ >8192 要素を処理すると、メモリ アクセス パターンが原因でプログラムの速度が大幅に低下するのはなぜですか?

8192 要素を処理すると、メモリ アクセス パターンが原因でプログラムの速度が大幅に低下するのはなぜですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-07 08:30:13205ブラウズ

Why Does My Program Slow Down Significantly When Processing 8192 Elements Due to Memory Access Patterns?

実行が遅いプログラムにおけるメモリ管理のジレンマ

プログラムが特定の数の要素、特に 8192 を反復処理すると、顕著な減速。この現象は、メモリ管理に起因しており、さらなる調査が必要な複雑なトピックです。

コードの概要

問題のループを考えてみましょう。事前定義された行列に対して演算を実行します。

for (i = 1; i < SIZE - 1; i++) {
    for (j = 1; j < SIZE - 1; j++) {
        res[j][i] = 0;
        for (k = -1; k < 2; k++)
            for (l = -1; l < 2; l++)
                res[j][i] += img[j + l][i + k];
        res[j][i] /= 9;
    }
}

プログラムのパフォーマンスの不一致は、採用されているメモリ レイアウトの種類によって発生します。配列にアクセスする場合、最新のプロセッサは効率を最適化するために連続したメモリ ブロックを優先します。ただし、提供されたコードの場合のように、ループが要素を非線形に反復する場合、プロセッサは非順次データにアクセスしようとしてメモリ ストールが発生する可能性があります。

Super-アライメントとキャッシュの問題

問題の核心は、プロセッサがメモリ ブロックに優先的にアクセスする現象である「スーパー アライメント」にあります。これは特定のサイズ (多くの場合 16 バイトまたは 32 バイト) の倍数です。この場合、外側のループは行を反復し、内側のループは列を反復します。 SIZE が 2048 の倍数の場合、外側のループは行間でメモリの大部分をスキップし、プロセッサがデータを待機している間に遅延が発生します。

パフォーマンスの比較

次の実行時間はパフォーマンスを示しています。影響:

SIZE = 8191: 3.44 secs
SIZE = 8192: 7.20 secs
SIZE = 8193: 3.18 secs

解決策: ループの並べ替え

この問題の解決策は、外側のループが行ではなく列を反復するようにループを再配置することです。これにより、プログラムが連続したメモリ ブロックにアクセスするようになり、速度低下の原因となる非順次アクセスが排除されます。

変更されたループ:

for (j = 1; j < SIZE - 1; j++) {
    for (i = 1; i < SIZE - 1; i++) {
        ... (same operations as before) ...
    }
}

この変更を実装すると、パフォーマンスの差異がなくなり、次の実行時間に見られるように:

SIZE = 8191: 0.376 seconds
SIZE = 8192: 0.357 seconds
SIZE = 8193: 0.351 seconds

以上が8192 要素を処理すると、メモリ アクセス パターンが原因でプログラムの速度が大幅に低下するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。