內存對齊將數據結構中的變量放置在特定邊界上,以提高內存訪問速度。在 c++++ 中,可以通過 attribute ((aligned)) 宏或 #pragma pack 指令 實現內存對齊。例如,將一個結構體成員對齊到 4 字節邊界可以顯著提高訪問該成員的數據的性能,因為現代計算機以 4 字節塊訪問內存。基準測試表明,對齊的結構體訪問速度比未對齊的快近一倍。
C++ 函數性能優化中的內存對齊技術
簡介
內存對齊是指將數據結構中的變量放置在內存地址上,使其能被特定大小的整數整除。在 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
登錄后復制
正如結果所示,對齊的結構體訪問速度比未對齊的結構體快了近一倍。