Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory alignment : how to use alignof / alignas?

I work with shared memory right now.

I can't understand alignof and alignas.

cppreference is unclear : alignof returns "alignment" but what is "alignment" ? number of bytes to add for the next block to be aligned ? padded size ? Stack overflow / blogs entries are unclear too.

Can someone explain clearly alignof and alignas ?

like image 375
Offirmo Avatar asked Jun 13 '13 15:06

Offirmo


People also ask

How does memory alignment work?

Alignment refers to the arrangement of data in memory, and specifically deals with the issue of accessing data as proper units of information from main memory. First we must conceptualize main memory as a contiguous block of consecutive memory locations. Each location contains a fixed number of bits.

What is the use of Alignas?

The alignas type specifier is a portable, C++ standard way to specify custom alignment of variables and user defined types. The alignof operator is likewise a standard, portable way to obtain the alignment of a specified type or variable.

What is Alignas in C?

alignas and _Alignas (C11) Use alignas or _Alignas to specify custom alignment for a variable or user-defined type. They can be applied to a struct, union, enumeration, or variable.

What does Alignof do in C++?

In C++11 the alignof operator used to returns the alignment, in bytes of the specified type. Syntax Explanation: alignof: operator returns the alignment in byte, required for instances of type, which type is either complete type, array type or a reference type.


2 Answers

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).

like image 64
CoffeDeveloper Avatar answered Sep 20 '22 12:09

CoffeDeveloper


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).

like image 44
Cubbi Avatar answered Sep 23 '22 12:09

Cubbi