Geheugenuitlijning (memory alignment) is het plaatsen van gegevens in het geheugen op adressen die een veelvoud zijn van een bepaald aantal bytes, overeenkomstig de architectuur of het datatypes. Juiste uitlijning is kritisch voor de prestaties, correcte werking met hardware en sommige processorinstructies.
Geschiedenis van het onderwerp.
In vroege computers leidde het niet naleven van uitlijning tot hardwarefouten (bus error), en de rekenkracht van processors was gevoelig voor niet-meervoudige gegevensadressen. Zelfs in moderne architecturen zorgt juiste uitlijning ervoor dat toegang tot gegevens in 1 cyclus plaatsvindt zonder penalti.
Probleem.
Als een structuur zonder rekening te houden met uitlijning is geplaatst, kan lezen/schrijven trager of onmogelijk zijn (bijvoorbeeld, crash op ARM of MIPS). Bovendien kan het leiden tot problemen met laag-niveau API's, apparaten of gegevensserialisatie voor netwerkoverdracht.
Oplossing.
In C++ zijn er sleutelwoorden zoals alignas (C++11) en std::align, evenals niet-standaard compilerattributen (__attribute__((aligned(N))) in GCC/Clang, __declspec(align(N)) in MSVC).
Voorbeeldcode:
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; }
Belangrijkste kenmerken:
Beïnvloedt de volgorde van leden in een struct de grootte en uitlijning van de struct?
Ja, de volgorde van leden bepaalt direct de "padds" tussen hen, wat extra bytes kan toevoegen aan de grootte van de structuur.
struct S1 { char a; int b; }; // meestal sizeof==8 (met 4-byte uitlijning) struct S2 { int b; char a; }; // meestal sizeof==8, maar soms minder padding
Kan de grootte van een struct worden verminderd zonder de uitlijning te schenden?
Ja, als grote leden eerder worden gegroepeerd en kleine later. Effectieve uitlijning van gegevens rekening houdend met de bits:
struct S { double d; int i; char c; }; // beter dan afzonderlijk
Wat gebeurt er als je handmatig met niet-uitgelijnde adressen werkt via pointers?
De C++ standaard verklaart dit gedrag als gedefinieerd (undefined behavior), sommige CPU's kunnen SIGBUS of een soortgelijk probleem geven.
Een programmeur implementeerde zijn eigen structuur voor het werken met SIMD, zonder de uitlijning op te geven. Hierdoor crasht het programma op sommige ARM-apparaten wanneer geprobeerd wordt met niet-uitgelijnde gegevens.
Voordelen:
Nadelen:
In een project dat met videogegevens werkt (SSE/AVX), werd alignas gebruikt voor bufferstructuren, wat altijd efficiënte uitvoering van SIMD-instructies mogelijk maakte.
Voordelen:
Nadelen: