반응형
Structure alignment
  - The alignment of a nonpacked structure is the maximum alignment required by any of its fields. - ARM
  - 구조체에서의 alignment 는 가장 큰 alignment에 맞추어진다.
    이는 자동 padding 과 연계되어 실수를 하기 쉬운 부분이 된다.

struct
{
    int a;
    double b;
    int c;
} TT;

TT의 sizeof 결과는 얼마일까? 답은 24이다.
왜냐하면 가장 큰 alignment 인 8 에 맞춰 남는 부분들이 padding 되기 때문이다.


padding
보통 우리가 아는 한에서는 4byte alignment 이다. 그리고 이보다 작을 경우에는 compiler 에서 자동 padding을 넣어준다. 이렇게 하는 이유는 performance 상의 이유이다. 메모리 접근시 유리하다.

packing 하기(packed 의 사용)
그러나 이러한 자동 padding 은 코드 호환성은 상당히 떨어진다.
왜냐하면 compiler 에 따라 자동 padding 하는 방식이 다를 수도 있기 때문이다. 그래서 performance를 떨어트리더라도 코드 호환성을 높이기 위해 자동 padding 을 하지 않게 된다.
즉, alignment 에 맞춰 padding을 넣지 않고 순수한 data가 차지하는 byte만을 메모리에 잡는다.

이렇게 하는 것을 packing 이라고 한다.


packing 하게 되면 기본적으로 alignment 를 1로 잡는다.

arm 계열
__packed 명령을 이용하여 packing 한다.
__align(n) 명령을 통해 특정 n byte 로 align이 가능하다.

gcc
__attribute__((packed))
__attribute__((align(n))) 과 같이 한다.

VC (MS 계열)
#pragma pack(push)
#pragma pack(4)
~~~~~~~~~
#pragma pack(pop)

VC 에서는 align 이 없고 pack 명령어를 통해 다 처리한다.
반응형
반응형

출처 : http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/compiler/ref/ruoptaln.htm


align
  


Purpose
Specifies what aggregate alignment rules the compiler uses for file compilation. Use this option to specify the maximum alignment to be used when mapping a class-type object, either for the whole source program or for specific parts.


Syntax



where available alignment options are:


power  The compiler uses a set of alignment rules to that provide binary compatibility with objects created by gcc V3.3 using the -malign option. This is the default.  
natural  The compiler uses a set of alignment rules to that provide binary compatibility with objects created by gcc V3.3 using the -malign option.  
mac68k  The compiler uses the Macintosh** alignment rules.  
bit_packed  The compiler uses the bit_packed alignment rules. Data, including bitfields, is packed as tightly as possible.  

See also #pragma align and #pragma options.


Notes
If you use the -qalign option more than once on the command line, the last alignment rule specified applies to the file.

You can control the alignment of a subset of your code by using #pragma align=alignment_rule. Use #pragma align=reset to revert to a previous alignment rule. The compiler stacks alignment directives, so you can go back to using the previous alignment directive, without knowing what it is, by specifying the #pragma align=reset directive. For example, you can use this option if you have a class declaration within an include file and you do not want the alignment rule specified for the class to apply to the file in which the class is included.

You can code #pragma align=reset in a source file to change the alignment option to what it was before the last alignment option was specified. If no previous alignment rule appears in the file, the alignment rule specified in the invocation command is used.


Examples
Example 1 - Affecting Only Aggregate Definition

Using the compiler invocation:

xlc++ file2.C /* <-- default alignment rule for file is                 */
            /*     power since no alignment rule specified */

Where file2.C has:

extern struct A A1;
typedef struct A A2;

#pragma options align=bit_packed /* <-- use bit_packed alignment rules*/
struct A {
  int a;
  char c;
};
#pragma options align=reset /* <-- Go back to default alignment rules */

struct A A1;  /* <-- aligned using bit_packed alignment rules since   */
A2 A3;        /*     this rule applied when struct A was defined      */

Example 2 - Imbedded #pragmas

Using the compiler invocation:

xlc -qalign=mac68k file.c  /* <-- default alignment rule for file is */
                           /*    Macintosh                           */

xlc -qalign=power file.c  /* <-- default alignment rule for file */
                           /*    is power                        */

Where file.c has:

struct A {
  int a;
  struct B {
    char c;
    double d;
#pragma options align=bit_packed /* <-- B will be unaffected by this  */
                            /*     #pragma, unlike previous behavior; */
                            /*     power alignment rules still    */
                            /*     in effect                          */
  } BB;
#pragma options align=reset /* <-- A is unaffected by this #pragma;   */
} AA;                       /*     power alignment rules still    */
                            /*     in effect                          */


Using the __align specifier
You can use the __align specifier to explicitly specify data alignment when declaring or defining a data item.


__align Specifier

Purpose
Use the __align specifier to explicitly specify alignment and padding when declaring or defining data items.


Syntax
declarator __align (int_const) identifier;

__align (int_const) struct_or_union_specifier [identifier] {struct_decln_list}

where:


int_const  Specifies a byte-alignment boundary. int_const must be an integer greater than 0 and equal to a power of 2.  


Notes
The __align specifier can only be used with declarations of first-level variables and aggregate definitions. It ignores parameters and automatics.

The __align specifier cannot be used on individual elements within an aggregate definition, but it can be used on an aggregate definition nested within another aggregate definition.

The __align specifier cannot be used in the following situations:

Individual elements within an aggregate definition.
Variables declared with incomplete type.
Aggregates declared without definition.
Individual elements of an array.
Other types of declarations or definitions, such as typedef, function, and enum.
Where the size of variable alignment is smaller than the size of type alignment.
Not all alignments may be representable in an object file.


Examples
Applying __align to first-level variables:

int __align(1024) varA;        /* varA is aligned on a 1024-byte boundary
                                   and padded with 1020 bytes              */

static int __align(512) varB;  /* varB is aligned on a 512-byte boundary
                                   and padded with 508 bytes               */

int __align(128) functionB( ); /* An error                                 */

typedef int __align(128) T;    /* An error                                 */

__align enum C {a, b, c};      /* An error                                 */

  

Applying __align to align and pad aggregate tags without affecting aggregate members:

__align(1024) struct structA {int i; int j;}; /* struct structA is aligned
                                                 on a 1024-byte boundary
                                                 with size including padding
                                                 of 1024 bytes             */

__align(1024) union unionA {int i; int j;}; /* union unionA is aligned
                                                 on a 1024-byte boundary
                                                 with size including padding
                                                 of 1024 bytes            */

  

Applying __align to a structure or union, where the size and alignment of the aggregate using the structure or union is affected:

__align(128) struct S {int i;};     /* sizeof(struct S) == 128             */

struct S sarray[10];                /* sarray is aligned on 128-byte boundary
                                       with sizeof(sarray) == 1280         */

struct S __align(64) svar;          /* error - alignment of variable is
                                         smaller than alignment of type    */

struct S2 {struct S s1; int a;} s2; /* s2 is aligned on 128-byte boundary
                                         with sizeof(s2) == 256 bytes      */

  

Applying __align to an array:

AnyType __align(64) arrayA[10]; /* Only arrayA is aligned on a 64-byte
                                  boundary, and elements within that array
                                  are aligned according to the alignment
                                  of AnyType.  Padding is applied after the
                                  back of the array and does not affect
                                  the size of the array member itself.    */

  

Applying __align where size of variable alignment differs from size of type alignment:

__align(64) struct S {int i;};

struct S __align(32) s1;          /* error, alignment of variable is smaller
                                     than alignment of type                 */

struct S __align(128) s2;         /* s2 is aligned on 128-byte boundary     */

struct S __align(16) s3[10];      /* error                                  */

int __align(1) s4;                /* error                                  */

__align(1) struct S {int i;};     /* error                                  */


Related References
Compiler Command Line Options
#pragma align
#pragma pack

See also:

The Data Mapping and Storage section of the VisualAge C++ Programming Tasks manual.
__attribute__((aligned)).
__attribute__((packed)).

반응형

+ Recent posts