Wyrównanie jest ograniczeniem, na którym można zapisać pierwszy bajt wartości w pamięci. (Konieczne jest poprawienie wydajności procesorów i zezwolenie na użycie niektórych instrukcji, które działają tylko na danych z określonym wyrównaniem, na przykład SSE musi być wyrównane do 16 bajtów, a AVX do 32 bajtów).
Wyrównanie 16 oznacza, że adresy pamięci będące wielokrotnością 16 są jedynymi prawidłowymi adresami.
alignas
wymuś wyrównanie do wymaganej liczby bajtów. Możesz wyrównać tylko do potęg 2: 1, 2, 4, 8, 16, 32, 64, 128, ...
#include <cstdlib>
#include <iostream>
int main() {
alignas(16) int a[4];
alignas(1024) int b[4];
printf("%p\n", a);
printf("%p", b);
}
przykładowe dane wyjściowe:
0xbfa493e0
0xbfa49000
1011 1111 1010 0100 1001 0011 1110 0000
1011 1111 1010 0100 1001 0000 0000 0000
drugie słowo kluczowe
alignof
jest bardzo wygodny, nie możesz zrobić czegoś takiego
int a[4];
assert(a % 16 == 0);
ale możesz to zrobić
assert(alignof(a) == 16);
assert(alignof(b) == 1024);
zauważ, że w rzeczywistości jest to bardziej rygorystyczne niż prosta operacja „%” (moduł). W rzeczywistości wiemy, że coś wyrównanego do 1024 bajtów jest koniecznie wyrównane do 1, 2, 4, 8 bajtów, ale
assert(alignof(b) == 32);
Aby być bardziej precyzyjnym, „alignof” zwraca największą potęgę 2 do tego, co jest wyrównane.
Również alignof jest dobrym sposobem, aby z góry poznać minimalne wymagania dotyczące dopasowania dla podstawowych typów danych (prawdopodobnie zwróci 1 dla znaków, 4 dla typu float itp.).
Nadal legalne:
alignas(alignof(float)) float SqDistance;
Coś z wyrównaniem 16 zostanie następnie umieszczone na następnym dostępnym adresie, który jest wielokrotnością 16 (może być niejawne wypełnienie od ostatnio używanego adresu).