__align in c++

C, C++, Visual C++, C++.Net Topics
Post Reply
SukhdeepMankoo
Lieutenant
Lieutenant
Posts: 92
Joined: Tue Oct 27, 2009 7:50 pm

__align in c++

Post by SukhdeepMankoo » Fri May 14, 2010 12:28 pm

Hi,
I have read that __align is used to set the boundary of variable, what is its benefit.
suppose __align(2) unsigned short u;

even unsigned short variable can have its value from 0 to 65535. then where is difference lies.
second thing, can we say that __align is a qualifier in c/c++.
Thanks.
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: __align in c++

Post by Neo » Fri May 14, 2010 4:19 pm

Data structure alignment is the way data is arranged and accessed in computer memory. It consists of two separate but related issues: data alignment and data structure padding. When a modern computer reads from or writes to a memory address, it will do this in word sized chunks (e.g. 4 byte chunks on a 32-bit system). Data alignment means putting the data at a memory offset equal to some multiple of the word size, which increases the system's performance due to the way the CPU handles memory. To align the data, it may be necessary to insert some meaningless bytes between the end of the last data structure and the start of the next, which is data structure padding.

For example, when the computer's word size is 4 bytes, the data to be read should be at a memory offset which is some multiple of 4. When this is not the case, e.g. the data starts at the 14th byte instead of the 16th byte, then the computer has to read two 4-byte chunks and do some calculation before the requested data has been read, or it may generate an alignment fault. Even though the previous data structure ends at the 14th byte, the next data structure should start at the 16th byte. Two padding bytes are inserted between the two data structures to align the next data structure to the 16th byte.

Definitions
A memory address a, is said to be n-byte aligned when n is a power of two and a is a multiple of n bytes. In this context a byte is the smallest unit of memory access, i.e. each memory address specifies a different byte. An n-byte aligned address would have log2(n) least-significant zeros when expressed in binary.

See this example.

Here is a structure with members of various types, totalling 8 bytes before compilation:

Code: Select all

struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
};
After compilation the data structure will be supplemented with padding bytes to ensure a proper alignment for each of its members:

Code: Select all

struct MixedData  /* after compilation */
{
    char Data1;
    char Padding1[1]; /* For the following 'short' to be aligned on a 2 byte boundary */
    short Data2;
    int Data3;  
    char Data4;
    char Padding2[3];
};
The compiled size of the structure is now 12 bytes. It is important to note that the last member is padded with the number of bytes required to conform to the largest type of the structure. In this case 3 bytes are added to the last member to pad the structure to the size of a long word.

It is possible to change the alignment of structures to reduce the memory they require (or to conform to an existing format) by reordering structure members or changing the compiler’s alignment (or “packing”) of structure members.

Code: Select all

struct MixedData  /* after reordering */
{
    char Data1;
    char Data4;   /* reordered */
    short Data2;
    int Data3;  
};
The compiled size of the structure now matches the pre-compiled size of 8 bytes.

There different directives for aligning on different compilers.

On Visual C++, we use something like below.

Code: Select all

#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */
 
struct MyPackedData
{
    char Data1;
    long Data2;
    char Data3;
};
 
#pragma pack(pop)   /* restore original alignment from stack */
if you use alinging for only one structure, we use,

Code: Select all

__declspec(align(32)) struct Str1{
   int a, b, c, d, e;
};
On CCS, since most of the C6000s are 128 bit alinged, we use #pragma DATA_ALIGN(array_name, 128) before the declaration of array.
SukhdeepMankoo
Lieutenant
Lieutenant
Posts: 92
Joined: Tue Oct 27, 2009 7:50 pm

Re: __align in c++

Post by SukhdeepMankoo » Fri May 21, 2010 2:57 pm

Thanks,
But i have seen that
__align(16) unsigned char buffer[20];

what will be its benefit here for declaring buffer of 20 elements which can store only value from 0 to 255?
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: __align in c++

Post by Neo » Fri May 21, 2010 3:19 pm

sukhdeepmankoo wrote:Thanks,
But i have seen that
__align(16) unsigned char buffer[20];

what will be its benefit here for declaring buffer of 20 elements which can store only value from 0 to 255?
First thing to note is, alignment is a requirement by the hardware architecture. It is just the hardware that needs buffers to be aligned to perform some of its instructions. So the compiler must guarantee aligned buffers on memory for the processing architecture.

In most of the C6000 DSP architectures, the External memory interface (EMIF) bus is 128-bit. If you do use EDMA (Enhanced Direct Memory Access) unit of the processor to transfer data, it requires you to align the buffers to 128-bit if you store them in SDRAM/DDR.

In the programmers point of view, there is no special requirement of having padding bytes but just a requirement of the processing architecture.
SukhdeepMankoo
Lieutenant
Lieutenant
Posts: 92
Joined: Tue Oct 27, 2009 7:50 pm

Re: __align in c++

Post by SukhdeepMankoo » Fri May 21, 2010 6:51 pm

Thanks,
It means if i declare
__align(128) unsigned char buffer[10];

then suppose address of buffer[0]=a
buffer[1]=a+128/8;
.....

is it right? but i have not seen this?
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: __align in c++

Post by Neo » Fri May 21, 2010 7:36 pm

sukhdeepmankoo wrote:Thanks,
It means if i declare
__align(128) unsigned char buffer[10];

then suppose address of buffer[0]=a
buffer[1]=a+128/8;
.....

is it right? but i have not seen this?
Since your array is defined with one type (single byte), according to my knowledge the alignment will happen as follows.

Code: Select all

| Byte1 | Byte2 | ........ | Byte9 | Byte10 | Pad_Byte1 | ..... | Pad_Byte6 |
Otherwise compiler might put another array/variable at the end of array "buffer" (at padding places above) which might be effected unnecessarily.

If we take the example of 20 bytes (__align(128) unsigned char buffer[20];) then it would be aligned as follows.

Code: Select all

| Byte1   | ................................................... |   Byte 16   |
| Byte17  | ........... | Byte20 | Pad_Byte 1 | ............... | Pad_Byte 12 |
SukhdeepMankoo
Lieutenant
Lieutenant
Posts: 92
Joined: Tue Oct 27, 2009 7:50 pm

Re: __align in c++

Post by SukhdeepMankoo » Sat May 22, 2010 12:03 pm

Thanks Neo.
Post Reply

Return to “C/C++ Programming”