Bellek hizalaması (memory alignment), verilerin bellek içinde belirli bir bayt sayısına, mimariye veya veri türüne uygun adreslerde yerleştirilmesidir. Doğru hizalama, performans, donanımla doğru çalışma ve bazı işlemci talimatları açısından kritik öneme sahiptir.
Meselenin geçmişi.
Erken bilgisayarlarda hizalama ihlalleri donanımsal hatalara (bus error) neden oluyordu ve işlemcilerin hesaplama gücü, uyumsuz veri adreslerine karşı hassastı. Modern mimarilerde doğru hizalama, verilere 1 saat döngüsünde erişim sağlar, ceza olmadan.
Sorun.
Eğer bir yapı hizalama göz önünde bulundurulmadan yerleştirilirse, okuma/yazma işlemleri daha yavaş olabilir veya mümkün olmayabilir (örneğin, ARM veya MIPS üzerinde çökme). Ayrıca, düşük seviyeli API'lerle, cihazlarla veya verilerin ağ üzerinden iletilmesi için serileştirme ile ilgili sorunlar yaşanır.
Çözüm.
C++'ta hizalamayı kontrol etmek için alignas anahtar kelimesi (C++11) ve std::align kullanılabilir, ayrıca derleyiciye özel öznitelikler (__attribute__((aligned(N))) GCC/Clang'da, __declspec(align(N)) MSVC'de) mevcuttur.
Kod örneği:
struct alignas(16) MyStruct { int a; double b; char c; }; #include <iostream> #include <type_traits> int main() { std::cout << alignof(MyStruct) << std::endl; // 16 std::cout << sizeof(MyStruct) << std::endl; }
Ana özellikler:
Struct üye bildirimlerinin sırası, yapının boyutunu ve hizalamasını etkiler mi?
Evet, üye sırası, aralarındaki "padding" değerlerini doğrudan etkiler ve bu, yapının boyutuna ek baytlar ekleyebilir.
struct S1 { char a; int b; }; // genellikle sizeof==8 (4 bayt hizalamasında) struct S2 { int b; char a; }; // genellikle sizeof==8, ama bazen daha az padding
Hizalamayı ihlal etmeden yapının boyutunu azaltmak mümkün mü?
Evet, büyük üyeleri önce gruplamak ve küçükleri sonra yerleştirmek mümkün. Verileri bit sayısına göre hizalamak etkilidir:
struct S { double d; int i; char c; }; // ayrı yerleştirmekten daha iyi
Manuel olarak hizalanmamış adreslerle iş yaparsak ne olur?
C++ standardı bu tür bir davranışı belirsiz (undefined behavior) olarak tanımlar, bazı CPU'lar SIGBUS veya benzeri hatalar verebilir.
Programcı, hizalamayı belirtmeden SIMD ile çalışacak bir yapı geliştirdi. Sonuçta, program bazı ARM cihazlarında hizalanmamış verilerle işlem yapmaya çalışırken çöküyor.
Artılar:
Eksiler:
Video verileri ile çalışan bir projede, yapıların hizalaması için alignas kullanıldı ve bu, her zaman SIMD talimatlarını etkili bir şekilde kullanmamıza olanak tanıdı.
Artılar:
Eksiler: