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é maximálně využít výhod hardwarové architektury.

Procesory čtou a zapisují paměť efektivněji, když ukládají data na adrese, která je násobek velikosti dat. Například k celočíselnému 4 bajtu se přistupuje efektivněji, pokud je uložené na adrese, která je násobkem 4. Pokud data nejsou zarovnaná, procesor více řeší výpočetní práci pro přístup k datům.

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

Kromě toho můžete zlepšit výkon mezipaměti tím, že sladíte často používaná data s velikostí řádku 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í o 32 bajtů.

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

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

Makra pro usnadnění alignof a alignas, definované v <stdalign.h>nástroji , se mapují přímo na _Alignof a _Alignas. 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 mezi těmito dvěma jazyky sdílíte libovolný kód.

alignas a _Alignas (C11)

K zadání vlastního zarovnání proměnné nebo uživatelem definovaného typu použijte alignas nebo _Alignas . Dají se 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, bit-field, funkce, parametr funkce nebo objektu deklarovaného pomocí specifikátoru register .

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

struct Typy a union mají zarovnání, které se rovná největšímu zarovnání ze všech členů. Bajty odsazení se přidávají v rámci objektu , struct aby se zajistilo splnění požadavků na zarovnání jednotlivých členů.

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

alignas Příklad

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

Zkompilujte pomocí /std:c11.

Windows SDK 10.0.20348.0 (verze 2104) nebo novější. Informace o stažení nejnovější sady SDK najdete v tématu Sada 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 (Zadejte standardní verzi jazyka.
C++ alignof a alignas
Zpracování zarovnání dat kompilátorem