Dela via


Justering (C11)

En av funktionerna på låg nivå i C är möjligheten att ange exakt justering av objekt i minnet för att dra största möjliga nytta av maskinvaruarkitekturen.

Processorer läser och skriver minne mer effektivt när de lagrar data på en adress som är en multipel av datastorleken. Ett heltal på 4 byte används till exempel effektivare om det lagras på en adress som är en multipel av 4. När data inte är justerade fungerar processorn mer adressberäkning för att komma åt data.

Som standard justerar kompilatorn data baserat på dess storlek: char på en gräns på 1 byte, short på en gräns på 2 byte, int, longoch float på en gräns på 4 byte, double på 8 bytes gräns och så vidare.

Genom att justera data som används ofta med processorns cachelinjestorlek kan du dessutom förbättra cacheprestandan. Anta till exempel att du definierar en struktur vars storlek är mindre än 32 byte. Du kanske vill använda justering på 32 byte för att säkerställa att alla instanser av strukturen cachelagras effektivt.

Vanligtvis behöver du inte oroa dig för justering. Kompilatorn justerar vanligtvis data efter naturliga gränser som baseras på målprocessorn och datastorleken. Data justeras på upp till 4 bytes gränser på 32-bitars processorer och 8 bytes gränser på 64-bitars processorer. I vissa fall kan du dock uppnå prestandaförbättringar eller minnesbesparingar genom att ange en anpassad justering för dina datastrukturer.

Använd nyckelordet _Alignof C11 för att hämta önskad justering av en typ eller variabel och _Alignas för att ange en anpassad justering för en variabel eller användardefinierad typ.

Bekvämlighetsmakronen alignof och alignas, som definieras i <stdalign.h>, mappas direkt till _Alignof_Alignasrespektive . Dessa makron matchar nyckelorden som används i C++. Därför kan det vara bra att använda makrona i stället för C-nyckelorden för kodportabilitet om du delar någon kod mellan de två språken.

alignas och _Alignas (C11)

Använd alignas eller _Alignas för att ange anpassad justering för en variabel eller användardefinierad typ. De kan tillämpas på en struct, union, uppräkning eller variabel.

alignas syntax

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

Anmärkningar

_Alignas kan inte användas i deklarationen av en typedef, bitfält, funktion, funktionsparameter eller ett objekt som deklarerats register med specificeraren.

Ange en justering som är en effekt på två, till exempel 1, 2, 4, 8, 16 och så vidare. Använd inte ett värde som är mindre än typens storlek.

struct och union typerna har en justering som är lika med den största justeringen för alla medlemmar. Utfyllnadsbyte läggs till i en struct för att säkerställa att enskilda medlemsjusteringskrav uppfylls.

Om det finns flera alignas specificerare i en deklaration (till exempel en struct med flera medlemmar som har olika alignas specificerare) blir justeringen struct av värdet för den största specificeraren minst.

alignas exempel

I det här exemplet används bekvämlighetsmakronet alignof eftersom det är portabelt till C++. Beteendet är detsamma om du använder _Alignof.

// 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 och _Alignof (C11)

_Alignof och dess alias alignof returnerar justeringen i byte av den angivna typen. Det returnerar ett värde av typen size_t.

alignof syntax

alignof(type)
_Alignof(type)

alignof exempel

I det här exemplet används bekvämlighetsmakronet alignof eftersom det är portabelt till C++. Beteendet är detsamma om du använder _Alignof.

// 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
    */
}

Kravspecifikation

Kompilera med /std:c11.

Windows SDK 10.0.20348.0 (version 2104) eller senare. Se Windows SDK för att ladda ned den senaste SDK:en. Instruktioner för att installera och använda SDK för C11- och C17-utveckling finns i Installera C11- och C17-stöd i Visual Studio.

Se även

/std (Ange språkstandardversion)
C++ alignof och alignas
Kompilatorhantering av datajustering