Share via


Perataan (C11)

Salah satu fitur tingkat rendah C adalah kemampuan untuk menentukan perataan objek dengan tepat dalam memori untuk memanfaatkan arsitektur perangkat keras secara maksimum.

CPU membaca dan menulis memori secara lebih efisien ketika menyimpan data di alamat yang merupakan kelipatan ukuran data. Misalnya, bilangan bulat 4 byte diakses lebih efisien jika disimpan di alamat yang merupakan kelipatan 4. Saat data tidak diratakan, CPU melakukan lebih banyak pekerjaan penghitungan alamat untuk mengakses data.

Secara default, pengompilasi meratakan data berdasarkan ukurannya: char pada batas 1 byte, short pada batas 2 byte, int, long, dan float pada batas 4 byte, double pada batas 8 byte, dan sebagainya.

Selain itu, dengan meratakan data yang sering digunakan dengan ukuran baris cache prosesor, Anda dapat meningkatkan performa cache. Misalnya, Anda menentukan struktur yang ukurannya kurang dari 32 byte. Anda mungkin ingin menggunakan perataan 32 byte untuk memastikan semua instans struktur telah di-cache secara efisien.

Biasanya, Anda tidak perlu khawatir tentang perataan. Pengompilasi umumnya menyelaraskan data pada batas alami yang didasarkan pada prosesor target dan ukuran data. Data diratakan hingga batas hingga 4 byte pada prosesor 32 byte, dan batas 8 byte pada prosesor 64 byte. Namun, dalam beberapa kasus, Anda dapat memperoleh peningkatan performa, atau penghematan memori, dengan menentukan perataan kustom untuk struktur data Anda.

Gunakan kata kunci C11 _Alignof untuk mendapatkan perataan jenis atau variabel pilihan, dan _Alignas untuk menentukan perataan kustom untuk variabel atau jenis yang ditentukan pengguna.

Makro kemudahan alignof dan alignas, didefinisikan dalam <stdalign.h>, petakan langsung masing-masing ke _Alignof dan _Alignas. Makro ini cocok dengan kata kunci yang digunakan dalam C++. Jadi, menggunakan makro alih-alih kata kunci C dapat berguna untuk portabilitas kode jika Anda membagikan kode apa pun antara dua bahasa.

alignas dan _Alignas (C11)

Gunakan alignas atau _Alignas untuk menentukan perataan kustom bagi variabel atau jenis yang ditentukan pengguna. Mereka dapat diterapkan pada struktur, gabungan, enumerasi, atau variabel.

alignas sintaks

alignas(type)
alignas(constant-expression)
_Alignas(type)
_Alignas(constant-expression)

Keterangan

_Alignas tidak dapat digunakan dalam deklarasi typedef, bidang bit, fungsi, parameter fungsi, atau objek yang dideklarasikan dengan penentu register.

Tentukan perataan yang merupakan pangkat dua, seperti 1, 2, 4, 8, 16, dan sebagainya. Jangan gunakan nilai yang lebih kecil dari ukuran jenis.

Jenis struct dan union memiliki perataan yang sama dengan perataan terbesar anggota mana pun. Byte padding ditambahkan dalam sebuah struct untuk memastikan persyaratan perataan anggota individual telah bertemu.

Jika ada beberapa penentu alignas dalam deklarasi (misalnya, struct dengan beberapa anggota yang memiliki penentu alignas yang berbeda), perataan struct akan setidaknya menjadi nilai penentu terbesar.

alignas contoh

Contoh ini menggunakan makro kemudahan alignof karena portabel ke C++. Perilakunya akan sama jika Anda menggunakan _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 dan _Alignof (C11)

_Alignof dan aliasnya alignof mengembalikan perataan dalam bit dari jenis yang ditentukan. Ini mengembalikan nilai jenis size_t.

alignof sintaks

alignof(type)
_Alignof(type)

alignof contoh

Contoh ini menggunakan makro kemudahan alignof karena portabel ke C++. Perilakunya sama jika anda menggunakan _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
    */
}

Persyaratan

Kompilasikan dengan /std:c11.

Windows SDK 10.0.20348.0 (versi 2104) atau yang lebih baru. Lihat Windows SDK untuk mengunduh SDK terbaru. Untuk instruksi menginstal dan menggunakan SDK untuk pengembangan C11 dan C17, lihat Menginstal dukungan C11 dan C17 di Visual Studio.

Lihat juga

/std (Menentukan Versi Standar Bahasa)
C++ alignof dan alignas
Penanganan pengompilasi perataan data