C++ memory alignment
Asked Answered
E

4

5

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 ?

Encyclopedic answered 6/7, 2015 at 21:45 Comment(3)
Arrays aren't concerned by alignment, only individual elements areRigney
Might want to site the exact caseAccording
There is no case really im just experimenting , all I could find was that regardless of variable size all it was always 4 byte aligned unless it was a 1 byte data type. Just curious to why .Encyclopedic
K
7

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.

Kastroprauxel answered 6/7, 2015 at 21:52 Comment(2)
I also tries with 16 byte byte data types that were still not aligned to 0x0. All I can say is that everything is 4 byte aligned regardless of size. Would some compilers do this differently or different CPUs ?Encyclopedic
@Student123: you'll want to use _aligned_malloc to get aligned memory for arrays and objects.Novelty
S
4

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.

Stupendous answered 6/7, 2015 at 22:8 Comment(3)
You can write your own operator new () and enforce alignmentAccording
Am I right in saying that along as a chunk of memory is 4 byte aligned the CPU will always make the most of the data and will not have to do more than one read to get any 4 byte variable ?Encyclopedic
@Encyclopedic I guess this will depend on the CPU. I would say that in general it's a good rule of thumb to follow. I know modern x86 microarchitectures don't penalise unaligned loads anymore.Stupendous
A
2

There is no guarantee of alignment

According answered 6/7, 2015 at 21:53 Comment(2)
@LegalizeIt it is the full answer, OP claimed that alignment should be something, I stated there is no guarentee. The rest of the answer was given in the 1st comment. An int can have an address that is odd, it likely won't, but it can.According
@scohe001 its an answerAccording
E
1

According to Intel® 64 and IA-32 Architectures Optimization Reference Manual (section B.4.5.2 Assists),

32-byte AVX store instructions that span two pages require an assist that costs roughly 150 cycles.

Eyeleteer answered 16/6, 2017 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.