Delen via


Uitlijning (C11)

Een van de functies op laag niveau van C is de mogelijkheid om de precieze uitlijning van objecten in het geheugen op te geven om optimaal te profiteren van de hardwarearchitectuur.

CPU's lezen en schrijven geheugen efficiënter wanneer ze gegevens opslaan op een adres dat een veelvoud van de gegevensgrootte is. Een geheel getal van 4 bytes wordt bijvoorbeeld efficiënter geopend als het wordt opgeslagen op een adres dat een veelvoud van 4 is. Wanneer gegevens niet zijn uitgelijnd, werkt de CPU meer adresberekeningen om toegang te krijgen tot de gegevens.

De compiler lijnt standaard gegevens uit op basis van de grootte: char op een grens van 1 byte, short op een grens van 2 bytes, intlongen float op een grens van 4 bytes, double op een grens van 8 bytes, enzovoort.

Daarnaast kunt u de cacheprestaties verbeteren door veelgebruikte gegevens uit te lijnen met de cacheregelgrootte van de processor. Stel dat u een structuur definieert waarvan de grootte kleiner is dan 32 bytes. U kunt 32 byte-uitlijning gebruiken om ervoor te zorgen dat alle exemplaren van de structuur efficiënt in de cache worden opgeslagen.

Meestal hoeft u zich geen zorgen te maken over uitlijning. De compiler lijnt doorgaans gegevens uit op natuurlijke grenzen die zijn gebaseerd op de doelprocessor en de grootte van de gegevens. Gegevens worden uitgelijnd op maximaal 4-bytegrenzen op 32-bits processors en 8-bytegrenzen op 64-bits processors. In sommige gevallen kunt u echter prestatieverbeteringen of geheugenbesparing bereiken door een aangepaste uitlijning voor uw gegevensstructuren op te geven.

Gebruik het trefwoord _Alignof C11 om de voorkeursuitlijning van een type of variabele op te halen en _Alignas een aangepaste uitlijning op te geven voor een variabele of door de gebruiker gedefinieerd type.

De gemaksmacro's alignof en alignas, gedefinieerd in <stdalign.h>, worden rechtstreeks toegewezen aan _Alignof en _Alignas, respectievelijk. Deze macro's komen overeen met de trefwoorden die worden gebruikt in C++. Het gebruik van de macro's in plaats van de C-trefwoorden kan dus handig zijn voor de overdracht van code als u code tussen de twee talen deelt.

alignas en _Alignas (C11)

Gebruik alignas of _Alignas om aangepaste uitlijning op te geven voor een variabele of door de gebruiker gedefinieerd type. Ze kunnen worden toegepast op een struct, samenvoeging, opsomming of variabele.

alignas syntaxis

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

Opmerkingen

_Alignas kan niet worden gebruikt in de declaratie van een typedef, bitveld, functie, functieparameter of een object dat is gedeclareerd met de register aanduiding.

Geef een uitlijning op die een macht van twee is, zoals 1, 2, 4, 8, 16, enzovoort. Gebruik geen waarde die kleiner is dan de grootte van het type.

struct en union typen hebben een uitlijning die gelijk is aan de grootste uitlijning van een lid. Opvullingsbytes worden toegevoegd binnen een struct om ervoor te zorgen dat aan de vereisten voor afzonderlijke ledenuitlijning wordt voldaan.

Als er verschillende alignas aanduidingen in een declaratie staan (bijvoorbeeld een struct met verschillende leden met verschillende alignas aanduidingen), is de uitlijning van de struct declaratie ten minste de waarde van de grootste aanduiding.

alignas voorbeeld

In dit voorbeeld wordt de handige macro alignof gebruikt omdat deze overdraagbaar is naar C++. Het gedrag is hetzelfde als u gebruikt _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 en _Alignof (C11)

_Alignof en de alias alignof retourneert de uitlijning in bytes van het opgegeven type. Het retourneert een waarde van het type size_t.

alignof syntaxis

alignof(type)
_Alignof(type)

alignof voorbeeld

In dit voorbeeld wordt de handige macro alignof gebruikt omdat deze overdraagbaar is naar C++. Het gedrag is hetzelfde als u gebruikt _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
    */
}

Behoeften

Compileer met /std:c11.

Windows SDK 10.0.20348.0 (versie 2104) of hoger. Zie Windows SDK om de nieuwste SDK te downloaden. Zie C11- en C17-ondersteuning installeren in Visual Studio voor instructies voor het installeren en gebruiken van de SDK voor C11- en C17-ontwikkeling.

Zie ook

/std (Taalstandaardversie opgeven)
C++ alignof en alignas
Compilerverwerking van gegevensuitlijning