Freigeben über


Ausrichtung (C11)

Eines der Features von C auf niedriger Ebene ist die Möglichkeit zum Angeben der präzisen Ausrichtung von Objekten im Speiche, um die Hardwarearchitektur optimal zu nutzen.

Das Lesen aus dem und Schreiben in den Arbeitsspeicher durch CPUs ist effizienter, wenn Daten an einer Adresse gespeichert werden, die ein Vielfaches der Datengröße ist. Beispielsweise wird auf einen 4-Byte-Integerwert effizienter zugegriffen, wenn er an einer Adresse gespeichert ist, die ein Vielfaches von 4 ist. Wenn die Daten nicht ausgerichtet sind, ist der CPU-Aufwand für die Adressberechnung größer, um auf die Daten zuzugreifen.

Standardmäßig richtet der Compiler Daten basierend auf ihrer Größe aus: char an einer 1-Byte-Grenze; short an einer 2-Byte-Grenze; int, long und float an einer 4-Byte-Grenze, double an einer 8-Byte-Grenze usw.

Darüber hinaus verbessern Sie durch die Ausrichtung häufig verwendeter Daten an der Cachezeilengröße des Prozessors die Cacheleistung. Angenommen, Sie definieren eine Struktur, deren Größe kleiner als 32 Bytes ist. Sie sollten dann eine 32-Byte-Ausrichtung verwenden, um sicherzustellen, dass alle Instanzen der Struktur effizient zwischengespeichert werden.

Normalerweise müssen Sie sich keine Gedanken bezüglich der Ausrichtung machen. Der Compiler richtet Daten in der Regel an natürlichen Grenzen aus, die auf dem Zielprozessor und der Größe der Daten basieren. Daten werden an bis zu 4-Byte-Grenzen mit 32-Bit-Prozessoren und 8-Byte-Grenzen mit 64-Bit-Prozessoren ausgerichtet. In einigen Fällen erzielen Sie jedoch Leistungsverbesserungen oder Speicherplatzeinsparungen, indem Sie eine benutzerdefinierte Ausrichtung für Ihre Datenstrukturen angeben.

Verwenden Sie das C11-Schlüsselwort _Alignof , um die bevorzugte Ausrichtung eines Typs oder einer Variablen zu erhalten, und _Alignas , um eine benutzerdefinierte Ausrichtung für eine Variable oder einen benutzerdefinierten Typ anzugeben.

Die Convenience-Makros alignof und alignas , die in <stdalign.h>definiert sind, sind direkt _Alignof bzw. _Alignas zugeordnet. Diese Makros entsprechen den in C++ verwendeten Schlüsselwörtern. Daher ist es möglicherweise hilfreich, die Makros aus Gründen der Codeportabilität anstelle der C-Schlüsselwörter zu verwenden, wenn Sie Code zwischen den beiden Sprachen freigeben.

alignas und _Alignas (C11)

Verwenden Sie alignas oder _Alignas , um die benutzerdefinierte Ausrichtung für eine Variable oder einen benutzerdefinierten Typ anzugeben. Sie können auf eine Struktur, eine Union, eine Enumeration oder eine Variable angewendet werden.

alignas-Syntax

alignas(type)
alignas(constant-expression)
_Alignas(type)
_Alignas(constant-expression)

Bemerkungen

_Alignas kann nicht in der Deklaration einer Typdefinition, eines Bitfelds, einer Funktion, eines Funktionsparameters oder eines mit dem register-Spezifizierer deklarierten Objekts verwendet werden.

Geben Sie eine Ausrichtung an, die eine Potenz von zwei ist, z. B. 1, 2, 4, 8, 16 usw. Verwenden Sie keinen Wert, der kleiner als die Größe des Typs ist.

struct - und union -Typen haben eine Ausrichtung, die der größten Ausrichtung eines beliebigen Members entspricht. In struct werden Auffüllbytes hinzugefügt, um sicherzustellen, dass die Ausrichtungsanforderungen einzelner Member erfüllt werden.

Wenn mehrere alignas-Spezifizierer in einer Deklaration vorhanden sind (z. B. struct mit mehreren Membern, die unterschiedliche alignas-Spezifizierer aufweisen), entspricht die Ausrichtung von struct mindestens dem Wert des größten Spezifizierers.

alignas-Beispiel

In diesem Beispiel wird das Convenience-Makro alignof verwendet, da es in C++ portierbar ist. Das Verhalten ist identisch, wenn Sie _Alignof verwenden.

// Compile with /std:c11

#include <stdio.h>
#include <stdalign.h>

typedef struct 
{
    int value; // aligns on a 4-byte boundary. There will be 28 bytes of padding between value and alignas
    alignas(32) char alignedMemory[32]; // assuming a 32 byte friendly cache alignment
} cacheFriendly; // this struct will be 32-byte aligned because alignedMemory is 32-byte aligned and is the largest alignment specified in the struct

int main()
{
    printf("sizeof(cacheFriendly): %d\n", sizeof(cacheFriendly)); // 4 bytes for int value + 32 bytes for alignedMemory[] + padding to ensure  alignment
    printf("alignof(cacheFriendly): %d\n", alignof(cacheFriendly)); // 32 because alignedMemory[] is aligned on a 32-byte boundary

    /* output
        sizeof(cacheFriendly): 64
        alignof(cacheFriendly): 32
    */
}

alignof und _Alignof (C11)

_Alignof und der zugehörige Alias alignof geben die Ausrichtung des angegebenen Typs in Bytes zurück. Es wird ein Wert vom Typ size_t zurückgegeben.

alignof-Syntax

alignof(type)
_Alignof(type)

alignof-Beispiel

In diesem Beispiel wird das Convenience-Makro alignof verwendet, da es in C++ portierbar ist. Das Verhalten ist identisch, wenn Sie _Alignof verwenden.

// Compile with /std:c11

#include <stdalign.h>
#include <stdio.h>

int main()
{
    size_t alignment = alignof(short);
    printf("alignof(short) = %d\n", alignment); // 2
    printf("alignof(int) = %d\n", alignof(int)); // 4
    printf("alignof(long) = %d\n", alignof(long)); // 4
    printf("alignof(float) = %d\n", alignof(float)); // 4
    printf("alignof(double) = %d\n", alignof(double)); // 8

    typedef struct
    {
        int a;
        double b;
    } test;

    printf("alignof(test) = %d\n", alignof(test)); // 8 because that is the alignment of the largest element in the structure

    /* output
        
       alignof(short) = 2
       alignof(int) = 4
       alignof(long) = 4
       alignof(float) = 4
       alignof(double) = 8
       alignof(test) = 8
    */
}

Anforderungen

Kompilieren Sie mit /std:c11.

Windows SDK 10.0.20348.0 (Version 2104) oder höher. Informationen zum Herunterladen des neuesten SDK finden Sie unter Windows SDK. Anweisungen zum Installieren und Verwenden des SDK für die C11- und C17-Entwicklung finden Sie unter Installieren der Unterstützung für C11 und C17 in Visual Studio.

Siehe auch

/std (Standardversion für die Sprache festlegen)
C++alignof und alignas
Compilerverarbeitung der Datenausrichtung