webentwicklung-frage-antwort-db.com.de

Speicherausrichtung: Wie benutzt man alignof / alignas?

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?

57
Offirmo

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.).

63
GameDeveloper

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.

7
Cubbi

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).

4
levengli