Aracılığıyla paylaş


Hizalama (C11)

C'nin alt düzey özelliklerinden biri, donanım mimarisinden en yüksek düzeyde yararlanmak için bellekteki nesnelerin hassas hizalamasını belirtebilme özelliğidir.

CPU'lar, verileri veri boyutunun katı olan bir adreste depoladığında belleği daha verimli bir şekilde okur ve yazar. Örneğin, 4 baytlık bir 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 bir sınıra, short 2 baytlık sınıra, int, longve float 4 baytlık sınıra, double 8 baytlık sınıra 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 az olan bir yapı tanımladığınız varsayalım. Yapının tüm örneklerinin verimli bir şekilde önbelleğe alındığından emin olmak için 32 baytlık hizalama kullanmak isteyebilirsiniz.

Genellikle hizalama konusunda endişelenmeniz gerekmez. Derleyici genellikle verileri hedef işlemciyi ve verilerin boyutunu temel alan doğal sınırlara hizalar. Veriler 32 bit işlemcilerde 4 baytlık sınırlara, 64 bit işlemcilerde ise 8 baytlık sınırlara hizalanır. Ancak bazı durumlarda, veri yapılarınız için özel bir hizalama belirterek performans geliştirmeleri veya bellek tasarrufu elde edebilirsiniz.

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)

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 typedef, 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 struct hizalaması en azından en büyük tanımlayıcının değeri olacaktır.

alignas Örnek

Bu örnek, C++ ile taşınabilir olduğundan kolaylık makrosunu alignof kullanır. kullanırsanı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++ ile taşınabilir olduğundan kolaylık makrosunu alignof kullanır. kullanırsanı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 /std:c11derleyin.

Windows SDK 10.0.20348.0 (sürüm 2104) veya üzeri. En son SDK'yi indirmek için bkz. Windows SDK. 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