メモリ アライメントは、データ構造内の変数を特定の境界に配置して、メモリ アクセス速度を向上させます。 C では、メモリのアラインメントは、属性 ((aligned)) マクロまたは #pragma Pack ディレクティブを通じて実現できます。たとえば、最近のコンピューターは 4 バイト ブロックでメモリにアクセスするため、構造体のメンバーを 4 バイトの境界に揃えると、そのメンバーのデータにアクセスするパフォーマンスが大幅に向上します。ベンチマーク テストでは、位置合わせされた構造は、位置合わせされていない構造のほぼ 2 倍の速度でアクセスされることが示されています。
はじめに
メモリ アライメントとは、データ構造を指します。変数 in は、特定のサイズの整数で割り切れるメモリ アドレスに配置されます。 C では、__attribute__ ((aligned))
マクロまたは #pragma Pack
ディレクティブを使用してメモリ アライメントを実現できます。
原則
現代のコンピューターは、キャッシュ ラインと呼ばれる特定のサイズのブロックでメモリにアクセスします。変数のアドレスがキャッシュ ライン境界と一致している場合、変数にアクセスするデータを一度にキャッシュにロードできます。これにより、メモリのアクセス速度が大幅に向上します。
実際的なケース
次の構造を考えてみましょう:
struct UnalignedStruct { int x; char y; double z; };
この構造は、メモリの 4 番目のワードにメンバーを配置していないため、位置合わせされていません。セクションの境界にあるアドレス。この構造体の位置合わせは、__attribute__ ((aligned))
マクロを使用して強制できます。
struct AlignedStruct { int x; char y __attribute__ ((aligned (4))); double z; };
これで、y
メンバーのアドレスが 4 に揃えられます。 -バイト境界。これにより、y
データへのアクセスのパフォーマンスが向上します。
パフォーマンスの向上
次のベンチマークは、アライメントされた構造とアライメントされていない構造のメモリ アクセス パフォーマンスを比較します:
#include <iostream> #include <benchmark/benchmark.h> struct UnalignedStruct { int x; char y; double z; }; struct AlignedStruct { int x; char y __attribute__ ((aligned (4))); double z; }; void BM_UnalignedAccess(benchmark::State& state) { UnalignedStruct s; for (auto _ : state) { benchmark::DoNotOptimize(s.y); // Prevent compiler optimization benchmark::ClobberMemory(); } } void BM_AlignedAccess(benchmark::State& state) { AlignedStruct s; for (auto _ : state) { benchmark::DoNotOptimize(s.y); // Prevent compiler optimization benchmark::ClobberMemory(); } } BENCHMARK(BM_UnalignedAccess); BENCHMARK(BM_AlignedAccess);
このベンチマークを実行すると、次の結果が生成されます:
Benchmark Time CPU Iterations ----------------------------------------------------------------------------------- BM_UnalignedAccess 12.598 ns 12.591 ns 5598826 BM_AlignedAccess 6.623 ns 6.615 ns 10564496
結果が示すように、アライメントされた構造のアクセス速度は、アライメントされていない構造のほぼ 2 倍になります。
以上がC++ 関数のパフォーマンス最適化におけるメモリ アライメント テクノロジの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。