Hizalama (C11)
C'nin alt düzey özelliklerinden biri, donanım mimarisinden en üst düzeyde yararlanmak için bellekteki nesnelerin tam hizalamasını belirtebilme özelliğidir.
CPU'lar, verileri veri boyutunun katları olan bir adreste depoladığında belleği daha verimli bir şekilde okur ve yazar. Örneğin, 4 baytlık tamsayıya, 4'ün katı olan bir adreste depolanıyorsa daha verimli bir şekilde erişilir. Veriler hizalanmamışsa CPU, verilere erişmek için daha fazla adres hesaplama işi yapar.
Varsayılan olarak, derleyici verileri boyutuna göre hizalar: char
1 baytlık sınırda, short
2 baytlık sınırda, int
, long
ve float
4 baytlık bir sınırda, double
8 baytlık sınırda vb.
Ayrıca, sık kullanılan verileri işlemcinin önbellek satırı boyutuyla hizalayarak önbellek performansını geliştirebilirsiniz. Örneğin, boyutu 32 bayttan küçük bir yapı tanımladığınız varsayalım. Yapının tüm örneklerinin verimli bir şekilde önbelleğe alınmasını sağlamak için 32 baytlık hizalama kullanmak isteyebilirsiniz.
Genellikle hizalama konusunda endişelenmeniz gerekmez. Derleyici genellikle verileri hedef işlemciye ve verilerin boyutuna göre doğal sınırlara hizalar. Veriler 32 bit işlemcilerde 4 baytlık sınırlara ve 64 bit işlemcilerde 8 baytlık sınırlara hizalanır. Ancak bazı durumlarda, veri yapılarınız için özel bir hizalama belirterek performans iyileştirmeleri veya bellek tasarrufu sağlayabilirsiniz.
Bir türün veya değişkenin tercih edilen hizalamasını almak ve _Alignas
bir değişken veya kullanıcı tanımlı tür için özel hizalama belirtmek için C11 anahtar sözcüğünü _Alignof
kullanın.
içinde tanımlanan <stdalign.h>
kolaylık makroları alignof
ve alignas
, sırasıyla doğrudan _Alignof
ve _Alignas
ile eşler. Bu makrolar C++ dilinde kullanılan anahtar sözcüklerle eşleşmektedir. Bu nedenle, iki dil arasında herhangi bir kod paylaşırsanız, C anahtar sözcükleri yerine makroları kullanmak kod taşınabilirliği için yararlı olabilir.
alignas
ve _Alignas
(C11)
Bir değişken veya kullanıcı tanımlı tür için özel hizalama belirtmek için veya _Alignas
kullanınalignas
. Bunlar bir yapıya, birleşime, numaralandırmaya veya değişkene uygulanabilir.
alignas
söz dizimi
alignas(type)
alignas(constant-expression)
_Alignas(type)
_Alignas(constant-expression)
Açıklamalar
_Alignas
tür tanımı, bit alanı, işlev, işlev parametresi veya tanımlayıcı ile bildirilen bir nesnenin bildiriminde register
kullanılamaz.
1, 2, 4, 8, 16 gibi iki güçte bir hizalama belirtin. Türün boyutundan daha küçük bir değer kullanmayın.
struct
ve union
türleri, herhangi bir üyenin en büyük hizalamasına eşit bir hizalamaya sahiptir. Tek tek üye hizalama gereksinimlerinin karşılandığından emin olmak için doldurma baytları içine struct
eklenir.
Bir bildirimde birkaç alignas
tanımlayıcı varsa (örneğin, farklı alignas
tanımlayıcılara sahip birkaç üyesi olan birstruct
), öğesinin hizalaması struct
en azından en büyük tanımlayıcının değeri olur.
alignas
örnek
Bu örnek, C++'a taşınabilir olduğundan kolaylık makrosunu alignof
kullanır. kullanıyorsanız _Alignof
davranış aynıdır.
// 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
ve _Alignof
(C11)
_Alignof
ve diğer adı alignof
belirtilen türün bayt cinsinden hizalamasını döndürür. türünde size_t
bir değer döndürür.
alignof
söz dizimi
alignof(type)
_Alignof(type)
alignof
örnek
Bu örnek, C++'a taşınabilir olduğundan kolaylık makrosunu alignof
kullanır. kullanıyorsanız _Alignof
davranış aynıdır.
// 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
*/
}
Gereksinimler
ile derleyin /std:c11
.
Windows SDK 10.0.20348.0 (sürüm 2104) veya üzeri. En son SDK'yı indirmek için bkz. Windows SDK' sı. C11 ve C17 geliştirmesi için SDK'yı yükleme ve kullanma yönergeleri için bkz . Visual Studio'da C11 ve C17 desteğini yükleme.
Ayrıca bkz.
/std
(Dil Standart Sürümünü Belirtin)
C++ alignof
ve alignas
Veri hizalama derleyicisi işleme