Data alignment considerations apply to the following kinds of variables:
Those that are dynamically allocated
Those that are members of a data structure
Those that are global or local variables
Those that are parameters passed on the stack
For best performance, align data as follows:
Align 8-bit data at any address.
Align 16-bit data to be contained within an aligned four byte word.
Align 32-bit data so that its base address is a multiple of four.
Align 64-bit data so that its base address is a multiple of eight.
Align 80-bit data so that its base address is a multiple of sixteen.
Align 128-bit data so that its base address is a multiple of sixteen.
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® Fortran Compiler naturally aligns individual data items when it can, certain Fortran statements can cause data items to become unaligned.
You can use the command-line option -align 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:
Carefully specify the order and sizes of data declarations to ensure naturally aligned data.
Start with the largest size numeric items first, followed by smaller size numeric items, and then non-numeric (character) data.
The following statements can cause unaligned data:
Common blocks (COMMON statement)
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 the -align commons or -align dcommons option, depending on the largest data size used. See Alignment Options.
Derived-type (user-defined) data
Derived-type data items are declared after a TYPE statement.
If your data includes derived-type data structures, you should use the -align records 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 option (default) ensures all data items are naturally aligned.
If you specify the SEQUENCE statement, the -align records option is prevented from adding necessary padding to avoid unaligned data (data items are packed) unless you specify the -align sequence option. When you use SEQUENCE , you should specify data declaration order so that all data items are naturally aligned.
Record structures (RECORD and STRUCTURE statements)
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 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 structure, or record structure, use one or both of the following:
For new programs or for programs where the source code declarations can be modified easily, plan the order of data declarations with care. For example, you should order variables in a COMMON statement such that numeric data is arranged from largest to smallest, followed by any character data (see the data declaration rules in Ordering Data Declarations to Avoid Unaligned Data below.
For existing programs where source code changes are not easily done or for array elements containing derived-type or record structures, you can use command line options to request that the compiler align numeric data by adding padding spaces where needed.
Other possible causes of unaligned data include unaligned actual arguments and arrays that contain a derived-type structure or record structure:
When actual arguments from outside the program unit are not naturally aligned, unaligned data access occurs. Intel Fortran assumes all passed arguments are naturally aligned and has no information at compile time about data that will be introduced by actual arguments during program execution.
For arrays where each array element contains a derived-type structure or record structure, the size of the array elements may cause some elements (but not the first) to start on an unaligned boundary.
Even if the data items are naturally aligned within a derived-type structure without the SEQUENCE statement or a record structure, the size of an array element might require use of the -align records option to supply needed padding to avoid some array elements being unaligned.
If you specify -align norecords or specify -vms without -align records, no padding bytes are added between array elements. If array elements each contain a derived-type structure with the SEQUENCE statement, array elements are packed without padding bytes regardless of the Fortran command options specified. In this case, some elements will be unaligned.
When the -align records option is in effect, the number of padding bytes added by the compiler for each array element is dependent on the size of the largest data item within the structure. The compiler determines the size of the array elements as an exact multiple of the largest data item in the derived-type structure without the SEQUENCE statement or a record structure. The compiler then adds the appropriate number of padding bytes. For instance, if a structure contains an 8-byte floating-point number followed by a 3-byte character variable, each element contains five bytes of padding (16 is an exact multiple of 8). However, if the structure contains one 4-byte floating-point number, one 4-byte integer, followed by a 3-byte character variable, each element would contain one byte of padding (12 is an exact multiple of 4).
During compilation, the Intel Fortran 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:
Double-check data declarations within common blocks, derived-type structures, or record structures to ensure all data items are naturally aligned (see the data declaration rules in the subsection below). Using modules to contain data declarations can ensure consistent alignment and use of such data.
Avoid the EQUIVALENCE statement or use it in a way that cannot cause unaligned data or data spanning natural boundaries.
Ensure that arguments passed from outside the program unit are naturally aligned.
Check that the size of array elements containing at least one derived-type structure or record structure causes array elements to start on aligned boundaries (see the previous subsection).
There are two ways unaligned data might be reported:
During compilation, warning messages are issued for any data items that are known to be unaligned, unless you specify the -warn noalignments (or -W0) option that suppresses all warnings.
During program execution, warning messages are issued for any data that is detected as unaligned. The message includes the address of the unaligned access.
Consider the following run-time message:
Unaligned access pid=24821 <a.out> va=140000154, pc=3ff80805d60, ra=1200017bc
This message shows that:
The statement accessing the unaligned data (program counter) is located at 3ff80805d60
The unaligned data is located at address 140000154
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 structure, record structure, or data items made equivalent by an EQUIVALENCE statement will be naturally aligned.
Use the following rules to prevent unaligned data:
Always define the largest size numeric data items first.
If your data includes a mixture of character and numeric data, place the numeric data first.
Add small data items of the correct size (or padding) before otherwise unaligned data to ensure natural alignment for the data that follows.
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
compiler options
-integer_size{16|32|64}
or -real_size{32|64|128}
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.
Using the suggested data declaration guidelines minimizes the need to use the -align keyword options to add padding bytes to ensure naturally aligned data. In cases where the -align keyword options are still needed, using the suggested data declaration guidelines can minimize the number of padding bytes added by the compiler.
The order of data items in a common statement determine the order in which the data items are stored. Consider the following declaration of a common block named x:
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 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 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
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 command-line options -align commons or -align dcommons option:
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.
Like common blocks, derived-type structures can contain multiple data items (members).
Data item components within derived-type structures are naturally aligned on up to 64-bit boundaries, with certain exceptions related to the use of the SEQUENCE statement and Fortran options. See Options Controlling Alignment for information about these exceptions.
Intel Fortran stores a derived data type as a linear sequence of values, as follows:
If you specify the SEQUENCE statement, the first data item is in the first storage location and the last data item is in the last storage location. The data items appear in the order in which they are declared. The Fortran options have no effect on unaligned data, so data declarations must be carefully specified to naturally align data. The -align sequence option specifically aligns data items in a SEQUENCE derived-type on natural boundaries.
If you omit the SEQUENCE statement, Intel Fortran adds the padding bytes needed to naturally align data item components, unless you specify the -align norecords option.
Consider the following declaration of array CATALOG_SPRING of derived-type PART_DT:
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