Ugrás a tartalomhoz

data structure alignment

A Wikiszótárból, a nyitott szótárból


Főnév

data structure alignment (tsz. data structure alignments)

  1. (informatika) A data structure alignment (adatstruktúra igazítása) C++-ban azt jelenti, hogy az adatszerkezetek (struktúrák, osztályok) memóriában való elhelyezkedését az architektúra és a CPU hatékony működéséhez igazítjuk. Ez fontos a teljesítmény szempontjából, mert a modern CPU-k optimalizálva vannak a bizonyos memóriacímen történő adatelérésre.

Miért fontos az alignment?

  1. Gyorsabb memóriahozzáférés – A processzor hatékonyabban tudja elérni az adatokat, ha azok az elvárt határokra esnek.
  2. Padding és memóriafelhasználás – A fordító kiegészítő bájtokat (padding) helyezhet el a struktúrában, hogy igazítsa az adatokat.
  3. Undefined Behavior elkerülése – Egyes architektúrák nem támogatják a nem megfelelően igazított memóriacímekről való olvasást.



Alignment szabályok

Minden adattagnak van egy alignment követelménye, ami azt jelenti, hogy csak bizonyos memóriacímen kezdődhet: - char: 1 bájtos igazítás - short: 2 bájtos igazítás - int / float: 4 bájtos igazítás - double: 8 bájtos igazítás (x86-on lehet 4 is)

Példa egy struktúrára padding nélkül:

struct A {
    char c;   // 1 bájt
    int i;    // 4 bájt
};

Ez első ránézésre 5 bájt, de a valóságban 8 bájt lesz, mert az int-nek 4 bájton kell kezdődnie, így a fordító 3 bájtot (padding) szúr be a char után.



Padding és optimalizálás

Ha a sorrendet módosítjuk, elkerülhetjük a felesleges paddinget:

struct B {
    int i;    // 4 bájt
    char c;   // 1 bájt
};

Ez is 8 bájt, de ha így alakítjuk:

struct C {
    char c;   // 1 bájt
    char d;   // 1 bájt
    int i;    // 4 bájt
};

Most 6 bájt helyett 8 bájt lesz, mert az int igazítása miatt be kell szúrni 2 padding bájtot.



Az alignas kulcsszó használata

A C++11 bevezette az alignas kulcsszót, amely lehetővé teszi az explicit igazítást:

struct D {
    alignas(8) int i;  // Az `i`-nek 8 bájtos címre kell kerülnie
    char c;
};

Az alignof operátor

Az alignof(T) megmutatja egy típus igazítási követelményeit:

#include <iostream>
#include <cstddef>

struct Test {
    char c;
    int i;
};

int main() {
    std::cout << "Alignment of char: " << alignof(char) << '\n';
    std::cout << "Alignment of int: " << alignof(int) << '\n';
    std::cout << "Alignment of Test: " << alignof(Test) << '\n';
}

Struktúra igazítás elkerülése (#pragma pack)

Ha kikapcsolnánk az igazítást (bár ez lassabb lehet), használhatjuk a #pragma pack direktívát:

#pragma pack(1)
struct E {
    char c;
    int i;
};
#pragma pack()

Ez garantálja, hogy nem lesz padding, de lehet, hogy a CPU nem tudja hatékonyan olvasni az adatokat.



Összegzés

  • A memóriaigazítás javítja a teljesítményt.
  • A fordító paddinget szúr be a megfelelő igazítás érdekében.
  • Az alignas és alignof segítségével szabályozhatjuk az igazítást.
  • A #pragma pack csökkenti a paddinget, de ronthatja a teljesítményt.