Memory alignment : how to use alignof / alignas?

后端 未结 4 528
星月不相逢
星月不相逢 2020-12-02 05:43

I work with shared memory right now.

I can\'t understand alignof and alignas.

cppreference is unclear : alignof return

相关标签:
4条回答
  • 2020-12-02 06:14

    Alignment is not padding (although padding is sometimes introduced to satisfy alignment requirements). It is an intrisic property of a C++ type. To put it in standardese (3.11[basic.align])

    Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier (7.6.2).

    0 讨论(0)
  • 2020-12-02 06:20

    Each type has an alignment requirement. Generally, this is so variables of the type can be accessed efficiently, without having to cause the CPU to generate more than one read/write access in order to reach any given member of the datatype. Furthermore, it also ensure efficient copying of the entire variable. alignof will return the alignment requirement for the given type.

    alignas is used to force an alignment on a datatype (so long as it is not less stringent that what alignof said datatype would return)

    0 讨论(0)
  • 2020-12-02 06:23

    Alignment is a property related with memory address. Simply we can say than if an address X is aligned to Z then x is a multiple of Z ,that is X = Zn+0. Here the important thing is Z is always a power of 2.

    Alignment is a property of a memory address, expressed as the numeric address modulo a power of 2. For example, the address 0x0001103F modulo 4 is 3. That address is said to be aligned to 4n+3, where 4 indicates the chosen power of 2. The alignment of an address depends on the chosen power of 2. The same address modulo 8 is 7. An address is said to be aligned to X if its alignment is Xn+0.

    The above statement is found on microsoft c++ reference .

    If a data item is stored in the memory with an address which is aligned to its size , then that data item is said to be naturally aligned , else misaligned. For eg : if an integer variable with size 4 bytes is stored in an address which is aligned to 4 , then we can say that the variable is naturally aligned , that is the address of the variable should be a multiple of 4.

    The compilers always tries to avoid misalignments . For simple datatypes the addresses are chosen such that it is a multiple of the size of the variable in bytes. The complier also pads suitably in the case of structures for natural alignment and access.Here the structure will be aligned to the maximum of the sizes of different data items in the structure.eg:

        struct abc
       {
            int a;
            char b;
       };
    

    Here the structure abc is aligned to 4 which is the size of int member which is obviously greater than 1 byte(size of char member).

    alignas

    This specifier is used to align user defined types like structure , class etc to a particular value which is a power of 2.

    alignof

    This is a kind of operator to get the value to which the structure or class type is aligned. eg:

    #include <iostream>
    struct alignas(16) Bar
    {
        int i; // 4 bytes
        int n; // 4 bytes
        short s; // 2 bytes
    };
    int main()
    {
        std::cout << alignof(Bar) << std::endl; // output: 16
    }
    
    0 讨论(0)
  • 2020-12-02 06:37

    Alignment is a restriction on which memory positions a value's first byte can be stored. (It is needed to improve performance on processors and to permit use of certain instructions that works only on data with particular alignment, for example SSE need to be aligned to 16 bytes, while AVX to 32 bytes.)

    Alignment of 16 means that memory addresses that are a multiple of 16 are the only valid addresses.

    alignas
    

    force alignment to the required number of bytes. You can only align to powers of 2: 1, 2, 4, 8, 16, 32, 64, 128, ...

    #include <cstdlib>
    #include <iostream>
    
    int main() {
        alignas(16) int a[4];
        alignas(1024) int b[4];
        printf("%p\n", a);
        printf("%p", b);
    }
    

    example output:

    0xbfa493e0
    0xbfa49000  // note how many more "zeros" now.
    // binary equivalent
    1011 1111 1010 0100 1001 0011 1110 0000
    1011 1111 1010 0100 1001 0000 0000 0000 // every zero is just a extra power of 2
    

    the other keyword

    alignof
    

    is very convenient, you cannot do something like

    int a[4];
    assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error
    

    but you can do

    assert(alignof(a) == 16);
    assert(alignof(b) == 1024);
    

    note that in reality this is more strict than a simple "%" (modulus) operation. In fact we know that something aligned to 1024 bytes is necessarily aligned to 1, 2, 4, 8 bytes but

     assert(alignof(b) == 32); // fail.
    

    So to be more precise, "alignof" returns the greatest power of 2 to wich something is aligned.

    Also alignof is a nice way to know in advance minimum alignment requirement for basic datatypes (it will probably return 1 for chars, 4 for float etc.).

    Still legal:

    alignas(alignof(float)) float SqDistance;
    

    Something with an alignment of 16 then will be placed on the next available address that is a multiple of 16 (there may be a implicit padding from last used address).

    0 讨论(0)
提交回复
热议问题