Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ memory alignment

So I read that when variables are declared in c++ if you want to get the optimum cache reads the memory should stick to its natural alignment. Example:

int a; // memory address should end in 0x0,0x4,0x8,0xC
int b[2]; // 8 bytes 0x0,0x8
int b[4]; // 16 bytes 0x0

But in practice these variables do not follow the "natural alignment" rules, a 16 byte variable was residing at a memory address that ended in 0xC. Why is this ?

like image 561
Student123 Avatar asked Jul 06 '15 21:07

Student123


People also ask

What is memory alignment C?

What is alignment? 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 memory padding and alignment in C?

Structure padding is a concept in C that adds the one or more empty bytes between the memory addresses to align the data in memory.

What is 64 bit alignment?

64-bit aligned is 8 bytes aligned). A memory access is said to be aligned when the data being accessed is n bytes long and the datum address is n-byte aligned. When a memory access is not aligned, it is said to be misaligned. Note that by definition byte memory accesses are always aligned.

What does 4 byte aligned mean?

A 1-byte variable (typically a char in C/C++) is always aligned. A 2-byte variable (typically a short in C/C++) in order to be aligned must lie at an address divisible by 2. A 4-byte variable (typically an int in C/C++) must lie at an address divisible by 4 and so on.


3 Answers

Natural memory alignment generally refers to the alignment of individual variables, not arrays of variables. Thus an array of 4 byte integers (as you apparently have above) is naturally aligned to a 4 byte boundary and not to the 16 byte boundary.

Natural memory alignment usually pertains to how the CPU's load/store instructions are architected and implemented, not the size of cache lines. The CPU does not load whole arrays at a time (except for vector loads). Thus the CPU doesn't really care if an integer it is loading is part of an array or not.

Vector loads, which do load small arrays at the same time, often do have stricter alignment requirements. For example, in order to do an aligned vector load on an x86, the item must be aligned to 16 bytes.

like image 183
Craig S. Anderson Avatar answered Oct 18 '22 18:10

Craig S. Anderson


C++ won't align anything on the cache line because for all intents and purposes it doesn't know there is a cache.

If you want something aligned on a 16-byte boundary try posix_memalign() for things on the heap, or (if using GCC) on the stack, int x __attribute__ ((aligned (16))). In C++11 there is the alignas specifier.

I don't know a way to call new() with a guaranteed alignment though.

like image 36
hayesti Avatar answered Oct 18 '22 20:10

hayesti


There is no guarantee of alignment

like image 2
Glenn Teitelbaum Avatar answered Oct 18 '22 20:10

Glenn Teitelbaum