Setting Data Type and Alignment

Alignment of data affects these kinds of variables:

For best performance, align data as follows:

Causes of Unaligned Data and Ensuring Natural Alignment

For optimal performance, make sure your data is aligned naturally. A natural boundary is a memory address that is a multiple of the data item's size. For example, a REAL (KIND=8) data item aligned on natural boundaries has an address that is a multiple of 8. An array is aligned on natural boundaries if all of its elements are so aligned.

All data items whose starting address is on a natural boundary are naturally aligned. Data not aligned on a natural boundary is called unaligned data.

Although the Intel® compiler naturally aligns individual data items when it can, certain Fortran statements can cause data items to become unaligned.

You can use the align command-option to ensure naturally aligned data, but you should check and consider reordering data declarations of data items within common blocks, derived-type structures, and record structures as follows:

The !DEC$ ATTRIBUTES ALIGN directive specifies the byte alignment for a variable. It is not supported for ALLOCATABLE/POINTER variables.

Common blocks (COMMON statement), derived-type data, and Fortran 77 record structures (RECORD statement) usually contain multiple items within the context of the larger structure.

The following statements can cause unaligned data:

Statement

Options

Description

Common blocks (COMMON statement)

commons or dcommons

The order of variables in the COMMON statement determines their storage order. Unless you are sure that the data items in the common block will be naturally aligned, specify either -align commons or -align dcommons (Linux*) or /align:commons or /align:dcommons (Windows*), depending on the largest data size used.

Refer to the User's Guide for detailed information on using these statements and options.

Derived-type
(user-defined) data

records or sequence

Derived-type data items are declared after a TYPE statement.

If your data includes derived-type data structures, you should use the -align records (Linux) or /align:records (Windows) option, unless you are sure that the data items in the derived-type structures will be naturally aligned.

If you omit the sequence statement, the -align records (Linux) or /align:records (Windows) option (default) ensures all data items are naturally aligned.

If you specify the SEQUENCE statement, the -align records (Linux) or /align:records (Windows) option is prevented from adding necessary padding to avoid unaligned data (data items are packed) unless you specify SEQUENCE. When you use SEQUENCE, you should specify data declaration order so that all data items are naturally aligned.

Record structures (RECORD and STRUCTURE statements)

record
or structure

Intel Fortran record structures usually contain multiple data items. The order of variables in the STRUCTURE statement determines their storage order. The RECORD statement names the record structure. Record structures are an Intel Fortran language extension.

If your data includes record structures, you should use the -align records (Linux) or /align:records (Windows) option, unless you are sure that the data items in the record structures will be naturally aligned.

EQUIVALENCE statements

 

EQUIVALENCE statements can force unaligned data or cause data to span natural boundaries. For more information, see the Intel® Fortran Language Reference.

To avoid unaligned data in a common block, derived-type data, or record structure (extension), use one or both of the following:

Other possible causes of unaligned data include unaligned actual arguments and arrays that contain a derived-type structure or Intel Fortran record structure as detailed below.

Checking for Inefficient Unaligned Data

During compilation, the Intel® compiler naturally aligns as much data as possible. Exceptions that can result in unaligned data are described above.

Because unaligned data can slow run-time performance, it is worthwhile to:

Consider the following run-time message:

Example

Unaligned access pid=24821 <a.out> va=140000154, pc=3ff80805d60, ra=1200017bc

This message shows that:

Ordering Data Declarations to Avoid Unaligned Data

For new programs or when the source declarations of an existing program can be easily modified, plan the order of your data declarations carefully to ensure the data items in a common block, derived-type data, record structure, or data items made equivalent by an EQUIVALENCE statement will be naturally aligned.

Use the following rules to prevent unaligned data:

When declaring data, consider using explicit length declarations, such as specifying a KIND parameter. For example, specify INTEGER(KIND=4) (or INTEGER(4)) rather than INTEGER. If you do use a default size (such as INTEGER, LOGICAL, COMPLEX, and REAL), be aware that the following compiler options can change the size of an individual field's data declaration size and thus can alter the data alignment of a carefully planned order of data declarations:

Platform

Compiler Option

Windows*

/4I or /4R

Linux*

-integer_size or -real_size

Using the suggested data declaration guidelines minimizes the need to use the -align keyword (Linux) or /align:keyword (Windows) options to add padding bytes to ensure naturally aligned data. In cases where the -align keyword (Linux) or /align:keyword (Windows) options are still needed, using the suggested data declaration guidelines can minimize the number of padding bytes added by the compiler.

Arranging Data Items in Common Blocks

The order of data items in a COMMON statement determines the order in which the data items are stored. Consider the following declaration of a common block named X:

Example

logical (kind=2) flag

integer          iarry_i(3)

character(len=5) name_ch

common /x/ flag, iarry_i(3), name_ch

As shown in Figure 1-1, if you omit the appropriate Fortran command options, the common block will contain unaligned data items beginning at the first array element of IARRY_I.

Figure 1-1 Common Block with Unaligned Data

As shown in Figure 1-2, if you compile the program units that use the common block with the -align commons (Linux) or /align:commons (Windows) option, data items will be naturally aligned.

Figure 1-2 Common Block with Naturally Aligned Data

Because the common block X contains data items whose size is 32 bits or smaller, specify the -align commons (Linux) or /align:commons (Windows) option. If the common block contains data items whose size might be larger than 32 bits (such as REAL (KIND=8) data), use the -align commons (Linux) or /align:commons (Windows) option.

If you can easily modify the source files that use the common block data, define the numeric variables in the COMMON statement in descending order of size and place the character variable last. This provides more portability, ensures natural alignment without padding, and does not require the Fortran command options -align commons (Linux) or -align dcommons (Windows) or -align commons (Linux) or /align:commons (Windows):

Example

LOGICAL (KIND=2) FLAG

INTEGER          IARRY_I(3)

CHARACTER(LEN=5) NAME_CH

COMMON /X/ IARRY_I(3), FLAG, NAME_CH

As shown in Figure 1-3, if you arrange the order of variables from largest to smallest size and place character data last, the data items will be naturally aligned.

Figure 1-3 Common Block with Naturally Aligned Reordered Data

When modifying or creating all source files that use common block data, consider placing the common block data declarations in a module so the declarations are consistent. If the common block is not needed for compatibility (such as file storage or Fortran 77 use), you can place the data declarations in a module without using a COMMON block.

Arranging Data Items in Derived-Type Data

Like common blocks, derived-type data may contain multiple data items (members).

Data item components within derived-type data will be naturally aligned on up to 64-bit boundaries, with certain exceptions related to the use of the SEQUENCE statement and Fortran options. See Alignment Options for links to resources about these exceptions.

Intel Fortran stores a derived data type as a linear sequence of values, as follows:

Consider the following declaration of array CATALOG_SPRING of derived-type PART_DT:

Example

MODULE DATA_DEFS

  TYPE PART_DT

    INTEGER           IDENTIFIER

    REAL              WEIGHT

    CHARACTER(LEN=15) DESCRIPTION

  END TYPE PART_DT

  TYPE (PART_DT) CATALOG_SPRING(30)

...

END MODULE DATA_DEFS

As shown in Figure 1-4, the largest numeric data items are defined first and the character data type is defined last. There are no padding characters between data items and all items are naturally aligned. The trailing padding byte is needed because CATALOG_SPRING is an array; it is inserted by the compiler when the -align records (Linux) or /align:records (Windows) option is in effect.

Figure 1-4 Derived-Type Naturally Aligned Data (in CATALOG_SPRING : ( ,))

Arranging Data Items in Intel Fortran Record Structures

Intel Fortran supports record structures provided by Intel Fortran. Intel Fortran record structures use the RECORD statement and optionally the STRUCTURE statement, which are extensions to the Fortran 77 and Fortran standards. The order of data items in a STRUCTURE statement determines the order in which the data items are stored.

Intel Fortran stores a record in memory as a linear sequence of values, with the record's first element in the first storage location and its last element in the last storage location. Unless you specify -align norecords (Linux) or /align:norecords (Windows) padding bytes are added if needed to ensure data fields are naturally aligned.

The following example contains a structure declaration, a RECORD statement, and diagrams of the resulting records as they are stored in memory:

Example

STRUCTURE /STRA/

  CHARACTER*1 CHR

  INTEGER*4 INT

END STRUCTURE

...

RECORD /STRA/ REC

 Figure 1-5 shows the memory diagram of record REC for naturally aligned records.

Figure 1-5 Memory Diagram of REC for Naturally Aligned Records