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, int
long
, 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
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro