Compaq Fortran
User Manual for
Tru64 UNIX and Linux Alpha Systems


Previous Contents Index

5.3.1 Causes of Unaligned Data and Ensuring Natural Alignment

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

The following declaration statements can force data to be unaligned:

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 Compaq Fortran record structure.

When actual arguments from outside the program unit are not naturally aligned, unaligned data access will occur. Compaq 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 Compaq Fortran 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 f90 -align options 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 f90 command options specified. In this case, some elements will be unaligned.

When -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).

For More Information:

On the -align keyword options, see Section 5.3.4.

5.3.2 Checking for Inefficient Unaligned Data

During compilation, the Compaq Fortran compiler naturally aligns as much data as possible. Exceptions that can result in unaligned data are described in Section 5.3.1.

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

There are two ways unaligned data might be reported:

5.3.3 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:

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.

5.3.3.1 Arranging Data Items in Common Blocks

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 5-1, if you omit the appropriate f90 command options, the common block will contain unaligned data items beginning at the first array element of IARRY_I.

Figure 5-1 Common Block with Unaligned Data


As shown in Figure 5-2, if you compile the program units that use the common block with the -align commons options, data items will be naturally aligned.

Figure 5-2 Common Block with Naturally Aligned Data


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

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 f90 command options -align commons or -align dcommons :


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 5-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 5-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 Compaq Fortran 77 use), you can place the data declarations in a module without using a common block.

5.3.3.2 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 f90 options. See Section 5.3.4 for information about these exceptions.

Compaq 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:


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 5-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 option is in effect.

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


5.3.3.3 Arranging Data Items in Compaq Fortran Record Structures

Compaq Fortran supports record structures provided by Compaq Fortran. Compaq Fortran record structures use the RECORD statement and optionally the STRUCTURE statement, which are extensions to the FORTRAN-77 and Fortran 95/90 standards. The order of data items in a STRUCTURE statement determine the order in which the data items are stored.

Compaq 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 , 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:


STRUCTURE /STRA/ 
  CHARACTER*1 CHR 
  INTEGER*4 INT 
END STRUCTURE 
   .
   .
   .
RECORD /STRA/ REC 

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

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


5.3.4 Options Controlling Alignment

The following options control whether the Compaq Fortran compiler adds padding (when needed) to naturally align multiple data items in common blocks, derived-type data, and Compaq Fortran record structures:

The default behavior is that multiple data items in derived-type data and record structures will be naturally aligned; data items in common blocks will not ( -align records with -align nocommons ). In derived-type data, using the SEQUENCE statement prevents -align records from adding needed padding bytes to naturally align data items.

5.4 Using Arrays Efficiently

The following sections discuss these: topics:

5.4.1 Accessing Arrays Efficiently

On Alpha systems, many of the array access efficiency techniques described in this section are applied automatically by the Compaq Fortran loop transformation optimizations (see Section 5.8.1) or by the KAP for Compaq Fortran for Compaq Tru64 UNIX Systems performance preprocessor (described in Section 5.1.1).

Several aspects of array use can improve run-time performance:

5.4.2 Passing Array Arguments Efficiently

In Fortran 95/90, there are two general types of array arguments:

When passing arrays as arguments, either the starting (base) address of the array or the address of an array descriptor is passed:

Passing an assumed-shape array or array pointer to an explicit-shape array can slow run-time performance. This is because the compiler needs to create an array temporary for the entire array. The array temporary is created because the passed array may not be contiguous and the receiving (explicit-shape) array requires a contiguous array. When an array temporary is created, the size of the passed array determines whether the impact on slowing run-time performance is slight or severe.

Table 5-3 summarizes what happens with the various combinations of array types. The amount of run-time performance inefficiency depends on the size of the array.

Table 5-3 Output Argument Array Types
Input Arguments Array Types Explicit-Shape Arrays Deferred-Shape and Assumed-Shape Arrays
Explicit-Shape Arrays Very efficient. Does not use an array temporary. Does not pass an array descriptor. Interface block optional. Efficient. Only allowed for assumed-shape arrays (not deferred-shape arrays). Does not use an array temporary. Passes an array descriptor. Requires an interface block.
Deferred-Shape and Assumed-Shape Arrays When passing an allocatable array, very efficient. Does not use an array temporary. Does not pass an array descriptor. Interface block optional.

When not passing an allocatable array, not efficient. Instead use allocatable arrays whenever possible.

Uses an array temporary. Does not pass an array descriptor. Interface block optional.

Efficient. Requires an assumed-shape or array pointer as dummy argument. Does not use an array temporary. Passes an array descriptor. Requires an interface block.


Previous Next Contents Index