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, longve 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 _Alignasile 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 _Alignofdavranış 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_tbir 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 _Alignofdavranış 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