Sign in to follow this  
akaitora

Memory Alignment

Recommended Posts

Hi. I am learning about memory alignment. I thought memory alignment was when you try to pack variables as compactly as possible in a data structure without leaving holes in memory. However according to the book "Game Engine Architecture" I am wrong. This books says for example that an object with 2 byte alignment resides only at even addresses that have a lsn of 0x0 or 0x2 or 0x4 etc. In that case, how would I make a 2 byte object 2 byte aligned? Would I have to use memory placement new to ensure I start at an even memory address? If I just call new, I will get a memory address that is available, not necessarily an even one. Please enlighten me.

Share this post


Link to post
Share on other sites
Assuming you're asking about C++, new and malloc() are guaranteed to return properly aligned memory for any standard C++ type. Ex: int, short, pointers, normal classes, etc. This guarantee does not extend to compiler extension types like __m128 for MSVC or classes that contain extension types.

Share this post


Link to post
Share on other sites
[quote name='akaitora' timestamp='1311542037' post='4839738']
This books says for example that an object with 2 byte alignment resides only at even addresses that have a lsn of 0x0 or 0x2 or 0x4 etc.
[/quote]
That's not strictly true, as some architectures can support unaligned access e.g. x86 (mostly). However, accesses to aligned data typically requires fewer processor cycles and so most compilers will align objects appropriately unless you tell them otherwise (with e.g. the pragmas you mentioned).

Share this post


Link to post
Share on other sites
So if a function requires you pass it a pointer to an 8 byte aligned memory location, would the following be acceptable?

char *buffer8ByteAligned = (char *) malloc(8);

or

char *buffer8ByteAligned = new char[8];

Will this give me a memory address at a multiple of 8? Thanks!

Share this post


Link to post
Share on other sites
[quote name='akaitora' timestamp='1311602572' post='4839987']
So if a function requires you pass it a pointer to an 8 byte aligned memory location, would the following be acceptable?

char *buffer8ByteAligned = (char *) malloc(8);

or

char *buffer8ByteAligned = new char[8];

Will this give me a memory address at a multiple of 8? Thanks!
[/quote]
No, this will just give you 8 bytes of memory which could have any alignment. This is probably what you're looking for:

[url="http://msdn.microsoft.com/en-us/library/8z34s9c6%28VS.80%29.aspx"]http://msdn.microsof...28VS.80%29.aspx[/url]

Share this post


Link to post
Share on other sites
Hi,

To control the alignment of local data or member data you can use the following compiler specific extensions:

For MSVC:
__declspec(align(boundary)) ([url="http://msdn.microsoft.com/en-us/library/83ythb65(v=vs.80).aspx"]http://msdn.microsoft.com/en-us/library/83ythb65(v=vs.80).aspx[/url])

For GCC:
__attribute__ ((aligned (boundary)))

For dynamic memory allocation, you can use [font=Consolas, Courier, monospace][size=2]_aligned_malloc()[/size][/font]
[font=Consolas, Courier, monospace][size=2]
[/size][/font]
[font=Consolas, Courier, monospace][size=2]
[/size][/font]
[font=Consolas, Courier, monospace][size=2]Hope this will help ![/size][/font]

Share this post


Link to post
Share on other sites
[quote name='procgen' timestamp='1311602995' post='4839992']
No, this will just give you 8 bytes of memory which could have any alignment.
[/quote]
It can't have "any" alignment. malloc() is guaranteed to give you a suitably aligned memory address for any object that doesn't rely on vendor extensions. If the compiler supports a standard object with 8 byte alignment, then malloc(8) will need to return a memory address with 8 byte alignment. Similarly, new char[] is defined to return memory suitably aligned for any standard object up to the allocated memory size. (See section 5.3.4 paragraph 10 in the current version of the C++ standard.)

Share this post


Link to post
Share on other sites
[quote name='akaitora' timestamp='1311542037' post='4839738']In that case, how would I make a 2 byte object 2 byte aligned?[/quote]
If you are using Visual C++ you can use _aligned_malloc (include <malloc.h>) to ensure your data is allocated at some (2^x) boundary in memory. To pack structs/classes (again assuming you are using Visual C++) you can use the [color="#0000FF"][url="http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx"]pack pragma[/url][/color] to disable padding them to fit the default alignment (8 bytes). However (from MSDN):

[i]If you change the alignment of a structure, it may not use as much space in memory, but you may see a decrease in performance or even get a hardware-generated exception for unaligned access. You can modify this exception behavior by using SetErrorMode.[/i]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this