Sdílet prostřednictvím


Zarovnání (C11)

Jednou z funkcí nízké úrovně jazyka C je schopnost určit přesné zarovnání objektů v paměti, aby bylo možné využít maximální výhody hardwarové architektury.

Procesory čtou a zapisují paměť efektivněji, když ukládají data na adrese, která je násobkem velikosti dat. Například 4 bajtové celé číslo se přistupuje efektivněji, pokud je uloženo na adrese, která je násobkem 4. Pokud data nejsou zarovnaná, procesor pro přístup k datům pracuje s více výpočty adres.

Ve výchozím nastavení kompilátor zarovná data na základě jeho velikosti: char na hranici 1 bajtů, short na 2 bajtové hranici, intlonga float na 4 bajtové hranici, double na 8 bajtové hranici atd.

Kromě toho můžete zlepšit výkon mezipaměti tím, že zarovnáte často používaná data s velikostí čáry mezipaměti procesoru. Řekněme například, že definujete strukturu, jejíž velikost je menší než 32 bajtů. Pokud chcete zajistit efektivní ukládání všech instancí struktury do mezipaměti, můžete použít zarovnání 32 bajtů.

Obvykle se nemusíte starat o zarovnání. Kompilátor obvykle zarovná data na přirozených hranicích založených na cílovém procesoru a velikosti dat. Data se zarovnají až na 4 bajtové hranice na 32bitových procesorech a 8 bajtů na 64bitových procesorech. V některých případech ale můžete dosáhnout vylepšení výkonu nebo úspor paměti zadáním vlastního zarovnání pro datové struktury.

Klíčové slovo _Alignof C11 slouží k získání upřednostňovaného zarovnání typu nebo proměnné a _Alignas k zadání vlastního zarovnání pro proměnnou nebo uživatelem definovaný typ.

Makra pohodlí alignof a alignas, definované v <stdalign.h>, mapovat přímo na _Alignof a _Alignas, v uvedeném pořadí. Tato makra odpovídají klíčovým slovům používaným v jazyce C++. Použití maker místo klíčových slov jazyka C proto může být užitečné pro přenositelnost kódu, pokud sdílíte jakýkoli kód mezi těmito dvěma jazyky.

alignas a _Alignas (C11)

Použijte alignas nebo _Alignas zadejte vlastní zarovnání pro proměnnou nebo uživatelem definovaný typ. Lze je použít na strukturu, sjednocení, výčet nebo proměnnou.

Syntaxe alignas

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

Poznámky

_Alignas nelze použít v deklaraci typedef, bitového pole, funkce, parametru funkce nebo objektu deklarovaného pomocí specifikátoru register .

Zadejte zarovnání, které je mocninou dvou, například 1, 2, 4, 8, 16 atd. Nepoužívejte hodnotu menší než velikost typu.

struct a union typy mají zarovnání rovnou největšímu zarovnání libovolného člena. Bajty odsazení se přidají do rozsahu, struct aby byly splněny požadavky na zarovnání jednotlivých členů.

Pokud v deklaraci existuje několik alignas specifikátorů (například struct s několika členy, které mají odlišné alignas specifikátory), bude zarovnání struct alespoň hodnoty největšího specifikátoru.

alignas příklad

V tomto příkladu se používá praktické makro alignof , protože je přenosné do jazyka C++. Chování je stejné, pokud používáte _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 a _Alignof (C11)

_Alignof a jeho alias alignof vrátí zarovnání v bajtech zadaného typu. Vrátí hodnotu typu size_t.

Syntaxe alignof

alignof(type)
_Alignof(type)

alignof příklad

V tomto příkladu se používá praktické makro alignof , protože je přenosné do jazyka C++. Chování je stejné, pokud používáte _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
    */
}

Požadavky

Zkompilovat pomocí /std:c11.

Windows SDK 10.0.20348.0 (verze 2104) nebo novější Nejnovější sadu SDK si můžete stáhnout ze sady Windows SDK . Pokyny k instalaci a použití sady SDK pro vývoj pro C11 a C17 najdete v tématu Instalace podpory C11 a C17 v sadě Visual Studio.

Viz také

/std (Určení standardní verze jazyka)
C++ alignof a alignas
Zpracování kompilátoru zarovnání dat