Chapter 4. Data Layout #pragma Directives
Prev |  | Next

## Chapter 4. Data Layout `#pragma` Directives

Table 4-1 lists the `#pragma` directives discussed in this chapter, along with a short description of each and the compiler versions in which the directive is supported.

Table 4-1. Data Layout `#pragma` Directives

#pragma | Short Description | Compiler Versions
--- | --- | ---
`#pragma align_symbol` | Specifies alignment of user variables, typically at cache-line or page boundaries. | 7.2 and later
`#pragma fill_symbol` | Tells the compiler to insert any necessary padding to ensure that the user variable does not share a cache-line or page with any other symbol. | 7.2 and later
`#pragma pack` | Controls the layout of structure offsets, such that the strictest alignment for any structure member will be n bytes, where n is 0, 1, 2, 4, 8, or 16. When n is 0, the compiler returns to default alignment for any subsequent struct definitions. | 7.0 and later

## `#pragma align_symbol`

The `#pragma align_symbol` directive specifies the alignment of user variables, typically at cache-line or page boundaries.

The syntax of the `#pragma align_symbol` directive is as follows:

    #pragma align_symbol [symbol, size]

The first argument to this directive is a symbol. The symbol can be a global or automatic variable, but it cannot be a formal parameter to a function, or an element of a structured type such as a structure or array.

The second argument, size, can be any one of the following:

- L1cacheline, a machine-specific first-level cache-line size, typically 32 bytes

- L2cacheline, a machine-specific second-level cache-line size, typically 128 bytes

- page, a machine specific page size, typically 16 Kilobytes

- a user-specified value, which must be a power of two

The `#pragma align_symbol` directive aligns the start of symbol at the specified alignment boundary.

For global variables, this directive must be specified where the variable is defined. The directive is optional where the variable is declared.

| Caution: When using the `#pragma align_symbol` directive, there are two points to keep in mind: The `#pragma align_symbol` directive is ineffective for local variables of fixed-size symbols, such as simple scalars or arrays of known size. Theis directive is most effective for stack-allocated arrays of dynamically determined size. A variable cannot have both `#pragma fill_symbol` and `#pragma align_symbol` directives applied to it.

Example 4-1. `#pragma align_symbol`

The following code fragment illustrates the use of the `#pragma align_symbol` directive:

    int x;
    /* x is a global variable */

    #pragma align_symbol (x, 32)
    /* x will start at a 32-byte boundary */

    #pragma align_symbol (x, 2)
    /* Error: cannot request an alignment
    lower than the natural alignment of the symbol. */

## `#pragma fill_symbol`

The `#pragma fill_symbol` directive instructs the compiler to insert any necessary padding to ensure that the user variable does not share a cache-line, page, or other specified block of memory with any other symbol.

The syntax of the `fill_symbol` pragma is as follows:

    #pragma fill_symbol [symbol, size]

The first argument to this pragma is a symbol. The symbol can be a global or automatic variable, but it cannot be a formal parameter to a function, or an element of a structured type such as a structure or array.

The second argument can be any one of the following:

- L1cacheline, a machine-specific first-level cache-line size, typically 32 bytes

- L2cacheline, a machine-specific second-level cache-line size, typically 128 bytes

- page, a machine specific page size, typically 16 kilobytes

- a user-specified value that must be a power of two

The `#pragma fill_symbol` directive pads the named symbol with additional storage so that the symbol is assured not to overlap with any other data item within the storage of the specified size. The additional padding required is heuristically divided between each end of the specified variable.

For instance, a `#pragma fill_symbol` directive for the L1cacheline guarantees that the specified symbol will not suffer from false-sharing (multiple, unrelated symbols sharing the same cache line) between multiple processors for the L1 cache line.

For global variables, this directive must be specified where the variable is defined. The directive is optional where the variable is declared.

A variable cannot have both `#pragma fill_symbol` and `#pragma align_symbol` directives applied to it.

Example 4-2. `#pragma fill_symbol`

The following code fragment illustrates the use of `#pragma fill_symbol`:

    double y;
    /* y is a global or local variable */
    #pragma fill_symbol (y, L2cacheline)
    /* Allocates extra storage
       both before and after y so that
       y is within an L2cacheline (128
       bytes) all by itself. */

## `#pragma pack`

The `#pragma pack` directive controls the layout of structure offsets. The strictest alignment for any structure member is the specified number of bytes (1, 2, 4, 8, or 16).

The syntax of the `#pragma pack` directive is as follows:

    #pragma pack [n]

The `#pragma pack` directive works according to the following rules:

- A struct type defined in the scope of a `#pragma pack` has up to n bytes of alignment, where n is 0, 1, 2, 4, 8, or 16. When n is 0, the compiler returns to default alignment for any subsequent structure definitions.

- The packed characteristics of the type apply wherever the type is used, even outside the scope of the pragma in which the type was declared.

- The scope of a `#pragma pack` ends with the next `#pragma pack`, hence this pragma does not nest. There is no way to “return” from one instance of the directive to a lexically earlier instance of the directive.

| Caution: SGI strongly discourages the use of `#pragma pack` , because it is a nonportable feature and the semantics of this directive may change in future compiler releases. A structure declaration must be subjected to identical instances of a `#pragma pack` directive in all files, or else misaligned memory accesses and erroneous structure member dereferencing may ensue. References to fields in packed structures may be less efficient than references to fields in unpacked structures. The `#pragma pack` directive is not supported for C++ in `-n32` and `-64` modes.

Prev | Table of Contents | Next
Chapter 3. C++ Instantiation #pragma Directives |  | Chapter 5. DSM Optimization #pragma Directives