Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Um dos recursos de baixo nível do C é a capacidade de especificar o alinhamento preciso de objetos na memória para tirar o máximo proveito da arquitetura de hardware.
As CPUs leem e gravam memória de forma mais eficiente quando armazenam dados em um endereço múltiplo do tamanho dos dados. Por exemplo, um inteiro de 4 bytes é acessado de forma mais eficiente se for armazenado em um endereço múltiplo de 4. Quando os dados não estão alinhados, a CPU faz mais trabalho de cálculo de endereços para acessar os dados.
Por padrão, o compilador alinha dados com base em seu tamanho: char em um limite de 1 byte, short em um limite de 2 bytes, int, long, e float em um limite de 4 bytes, double no limite de 8 bytes e assim por diante.
Além disso, alinhando os dados usados com freqüência com o tamanho da linha de cache do processador, você pode melhorar o desempenho do cache. Por exemplo, digamos que você defina uma estrutura cujo tamanho é inferior a 32 bytes. Você pode querer usar o alinhamento de 32 bytes para garantir que todas as instâncias da estrutura sejam armazenadas em cache de forma eficiente.
Normalmente, você não precisa se preocupar com o alinhamento. O compilador geralmente alinha dados em limites naturais que são baseados no processador de destino e no tamanho dos dados. Os dados são alinhados em limites de até 4 bytes em processadores de 32 bits e limites de 8 bytes em processadores de 64 bits. Em alguns casos, no entanto, você pode obter melhorias de desempenho, ou economia de memória, especificando um alinhamento personalizado para suas estruturas de dados.
Use a palavra-chave _Alignof C11 para obter o alinhamento preferencial de um tipo ou variável e _Alignas para especificar um alinhamento personalizado para uma variável ou tipo definido pelo usuário.
As macros de alignof conveniência e alignas, definidas em <stdalign.h>, mapeiam diretamente para _Alignof e _Alignas, respectivamente. Essas macros correspondem às palavras-chave usadas em C++. Portanto, usar as macros em vez das palavras-chave C pode ser útil para a portabilidade do código se você compartilhar qualquer código entre os dois idiomas.
alignas e _Alignas (C11)
Use alignas ou _Alignas para especificar o alinhamento personalizado para uma variável ou tipo definido pelo usuário. Eles podem ser aplicados a uma struct, união, enumeração ou variável.
alignas sintaxe
alignas(type)
alignas(constant-expression)
_Alignas(type)
_Alignas(constant-expression)
Observações
_Alignas não pode ser usado na declaração de um typedef, bit-field, function, function parameter ou um objeto declarado com o register especificador.
Especifique um alinhamento que seja uma potência de dois, como 1, 2, 4, 8, 16 e assim por diante. Não use um valor menor do que o tamanho do tipo.
struct e union os tipos têm um alinhamento igual ao maior alinhamento de qualquer membro. Os bytes de preenchimento são adicionados dentro de um struct para garantir que os requisitos de alinhamento de membros individuais sejam atendidos.
Se houver vários alignas especificadores em uma declaração (por exemplo, um struct com vários membros que têm especificadores diferentes alignas ), o alinhamento do struct será pelo menos o valor do maior especificador.
alignas exemplo
Este exemplo usa a macro alignof de conveniência porque é portátil para C++. O comportamento é o mesmo se você usar _Alignofo .
// 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 e _Alignof (C11)
_Alignof e seu alias alignof retorna o alinhamento em bytes do tipo especificado. Ele retorna um valor do tipo size_t.
alignof sintaxe
alignof(type)
_Alignof(type)
alignof exemplo
Este exemplo usa a macro alignof de conveniência porque é portátil para C++. O comportamento é o mesmo se você usar _Alignofo .
// 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
*/
}
Requerimentos
Compilar com /std:c11.
Windows SDK 10.0.20348.0 (versão 2104) ou posterior. Consulte SDK do Windows para baixar o SDK mais recente. Para obter instruções sobre como instalar e usar o SDK para desenvolvimento C11 e C17, consulte Instalar suporte a C11 e C17 no Visual Studio.
Ver também
/std (Especificar versão padrão do idioma)
C++ alignof e alignas
Tratamento do compilador do alinhamento de dados