Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSVC default memory alignment of 8

According to MSDN, the /Zp command defaults to 8, which means 64-bit alignment boundaries are used. I have always assumed that for 32-bit applications, the MSVC compiler will use 32-bit boundaries. For example:

struct Test
{
   char foo;
   int bar;
};

The compiler will pad it like so:

struct Test
{
   char foo;
   char padding[3];
   int bar;
};

So, since /Zp8 is used by default, does that mean my padding becomes 7+4 bytes using the same example above:

struct Test
{
   char foo;
   char padding1[7];
   int bar;
   char padding2[4];
}; // Structure has 16 bytes, ending on an 8-byte boundary

This is a bit ridiculous isn't it? Am I misunderstanding? Why is such a large padding used, it seems like a waste of space. Most types on a 32-bit system aren't even going to use 64-bits, so the majority of variables would have padding (probably over 80%).

like image 440
void.pointer Avatar asked Dec 07 '11 04:12

void.pointer


People also ask

What is 64 byte aligned address?

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 is align in memory?

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 C++ alignment?

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.

How do I know if my memory is properly aligned?

How can the technician guarantee that the memory is correctly aligned? The label on the memory module should always face the CPU. A notch in the memory module should be aligned with a notch in the memory slot. The arrows on the memory module should be aligned with the arrows on the motherboard slot.


2 Answers

That's not how it works. Members are aligned to a multiple of their size. Char to 1 byte, short to 2, int to 4, double to 8. The structure is padded at the end to ensure the members still align correctly when the struct is used in an array.

A packing of 8 means it stops trying to align members that are larger than 8. Which is a practical limit, the memory allocator doesn't return addresses aligned better than 8. And double is brutally expensive if it isn't aligned properly and ends up straddling a cache line. But otherwise a headache if you write SIMD code, it requires 16 byte alignment.

like image 108
Hans Passant Avatar answered Oct 05 '22 01:10

Hans Passant


That does not mean every member is aligned on an 8byte boundary. Read a little more carefully:

the smaller member type or n-byte boundaries

The key here is the first part- "smaller member type". That means that members with less alignment might be aligned less, effectively.

struct x {
    char c;
    int y;
};
std::cout << sizeof(x);
std::cout << "offsetof(x, c) = " << offsetof(x, c) << '\n';
std::cout << "offsetof(x, c) = " << offsetof(x, y) << '\n';

This yields 8, 0, 4- meaning that in fact, the int is only padded to a 4byte alignment.

like image 25
Puppy Avatar answered Oct 05 '22 03:10

Puppy