Ich arbeite gerade mit Shared Memory.
Ich kann alignof
und alignas
nicht verstehen.
cppreference ist unklar: alignof
gibt "Ausrichtung" zurück, aber was ist "Ausrichtung"? Anzahl der Bytes, die für den nächsten auszurichtenden Block hinzugefügt werden sollen? gepolsterte Größe? Stapelüberlauf /Blog-Einträge sind ebenfalls unklar.
Kann jemand klar erklären, alignof
und alignas
?
Die Ausrichtung ist eine Einschränkung, auf welchen Speicherpositionen das erste Byte eines Werts gespeichert werden kann. (Es ist erforderlich, um die Leistung auf Prozessoren zu verbessern und die Verwendung bestimmter Anweisungen zu ermöglichen, die nur für Daten mit einer bestimmten Ausrichtung funktionieren, z. B. SSE müssen auf 16 Byte und AVX auf 32 Byte ausgerichtet werden .)
Die Ausrichtung von 16 bedeutet, dass Speicheradressen, die ein Vielfaches von 16 sind, die einzigen gültigen Adressen sind.
alignas
ausrichtung auf die erforderliche Anzahl von Bytes erzwingen (cppreference erwähnt dies nicht, aber ich denke, Sie können nur auf Potenzen von 2 ausrichten: 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);
}
beispielausgabe:
0xbfa493e0
0xbfa49000 // note how many more "zeros" now.
// binary equivalent
1011 1111 1010 0100 1001 0011 1110 0000
1011 1111 1010 0100 1001 0000 0000 0000 // every zero is just a extra power of 2
das andere Schlüsselwort
alignof
ist sehr praktisch, sowas kann man nicht machen
int a[4];
assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error
aber du kannst tun
assert(alignof(a) == 16);
assert(alignof(b) == 1024);
beachten Sie, dass dies in Wirklichkeit strenger ist als eine einfache "%" -Operation (Modul). Tatsächlich wissen wir, dass etwas, das auf 1024 Bytes ausgerichtet ist, notwendigerweise auf 1, 2, 4, 8 Bytes ausgerichtet ist, aber
assert(alignof(b) == 32); // fail.
Genauer gesagt gibt "alignof" die größte Potenz von 2 an, zu der etwas ausgerichtet ist.
Außerdem ist alignof eine gute Möglichkeit, die Mindestanforderung für die Ausrichtung grundlegender Datentypen im Voraus zu kennen (es wird wahrscheinlich 1 für Zeichen, 4 für Float usw. zurückgeben).
Immer noch legal:
alignas(alignof(float)) float SqDistance;
Etwas mit einer Ausrichtung von 16 wird dann an der nächsten verfügbaren Adresse platziert, die ein Vielfaches von 16 ist. (Es kann ein implizites Auffüllen von der zuletzt verwendeten Adresse geben.).
Ausrichtung ist keine Polsterung (obwohl manchmal eine Polsterung eingeführt wird, um die Ausrichtungsanforderungen zu erfüllen). Es ist eine intrisische Eigenschaft eines C++ - Typs. Um es auf Standard zu bringen (3.11[basic.align]
)
Für Objekttypen gelten Ausrichtungsanforderungen (3.9.1, 3.9.2), die die Adressen einschränken, denen ein Objekt dieses Typs zugewiesen werden kann. Eine Ausrichtung ist ein durch die Implementierung definierter ganzzahliger Wert, der die Anzahl der Bytes zwischen aufeinanderfolgenden Adressen darstellt, an denen ein bestimmtes Objekt zugewiesen werden kann. Ein Objekttyp legt für jedes Objekt dieses Typs eine Ausrichtungsanforderung fest. Eine strengere Ausrichtung kann mithilfe des Ausrichtungsspezifizierers (7.6.2) angefordert werden.
Jeder Typ hat eine Ausrichtungsanforderung. Im Allgemeinen ist dies so, dass auf Variablen des Typs effizient zugegriffen werden kann, ohne dass die CPU mehr als einen Lese-/Schreibzugriff generieren muss, um ein bestimmtes Mitglied des Datentyps zu erreichen. Darüber hinaus wird ein effizientes Kopieren der gesamten Variablen sichergestellt. alignof
gibt die Ausrichtungsanforderung für den angegebenen Typ zurück.
alignas
wird verwendet, um ein Alignment für einen Datentyp zu erzwingen (solange es nicht weniger streng ist als das, was alignof
diesen Datentyp zurückgeben würde).