5-3 ALIGNMENT OF DATA
**********************
Alignment is putting data and code in the computer memory in addresses
that are more efficient for the hardware to access (at the price of
wasting some memory).
The hardware of 'modern' RISC machines reads from memory in multi-byte
'chunks', usually 4 or 8 bytes long, these 'chunks' must begin at
addresses that are multiples of the 'chunk' size. Memory accesses to
misaligned addresses are emulated by multiple aligned accesses and
is much slower, or may generate 'bus errors' and abort the program.
Older computers (e.g. VAX), can handle misaligned (i.e. byte aligned)
memory accesses more gracefully, it just slows them. Memory was once
very costly, and computer designers couldn't afford to waste even
a small amount on alignment. Some new computers like sun4 series and
SGI can emulate this behaviour if you use special libraries, again at
the cost of degrading performance.
Code alignment is usually controlled by the compiler and there is
little you can do about it.
Practical considerations
------------------------
Integer and float data types sizes are usually a multiple of 4 bytes,
if you have only these types you have automatically longword (32 bits)
alignment, each number will start on a longword boundary.
Longword alignment is usually sufficient, except on 64 bit machines
when using 8 bytes data types, then you will need quadword alignment.
The problems start when you use the smaller types like character or
byte. Put them at the end of declaration lists, argument lists, and
common blocks, there they will cause less harm.
A little example program (that assumes the ASCII code, one-byte
characters, and four-byte integers), of course using EQUIVALENCE,
or some non-standard features would result in a nicer program:
PROGRAM ALIGN
C ------------------------------------------------------------------
INTEGER
* I, J, K,
* ASCII_ARROW, ASCII_SPACE, LONG_ARROW
C ------------------------------------------------------------------
CHARACTER
* CH*1, CHAR_ARROW
C ------------------------------------------------------------------
PARAMETER(
* CHAR_ARROW = '>',
* ASCII_ARROW = 62,
* ASCII_SPACE = 32,
* LONG_ARROW = ASCII_ARROW +
* ASCII_SPACE * (256 + 256**2 + 256**3))
C ------------------------------------------------------------------
I = LONG_ARROW
J = LONG_ARROW
K = LONG_ARROW
CH = CHAR_ARROW
C ------------------------------------------------------------------
CALL SUB(I, CH, J, K)
C ------------------------------------------------------------------
END
SUBROUTINE SUB(ARRAY)
C ------------------------------------------------------------------
CHARACTER
* ARRAY*13
C ------------------------------------------------------------------
WRITE (*,'(1X,1A13)') ARRAY
WRITE (*,'(1X,13I1)') 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0
C ------------------------------------------------------------------
RETURN
END
If your compiler doesn't automatically aligns data, you will see that
the CHARACTER*1 variable misaligns the last two INTEGER variables.
Automatic alignment may be inhibited with a compiler switch (see the
'compiler switches' chapter).
Excerpt from VMS documentation
------------------------------
Aligned data can provide significant performance
improvements on VAX systems (up to 4 times faster) and
on AXP systems (up to 100 times faster). Unaligned data
was typical on older VAX systems where minimal consumption
of memory was very important and data was packed tightly
together, ignoring alignment issues.
If you share data between AXP and VAX systems, avoid
unaligned data structures. Use at least longword alignment
for in-memory data structures whenever possible; quadword
alignment is preferred, if possible.
If you have a real-time application or an application that
exhibits poor file I/O characteristics and shares data through
a file, you may find it advantageous to align the file data
structures.
"Natural Alignment" and the FORTRAN 77 standard
-----------------------------------------------
Automatically padding variables so they begin on addresses that are
a multiple of their size (sometimes called "natural alignment")
solves all alignment problems, but may "break" standard-conforming
programs.
The FORTRAN standard requires procedure arguments and common-block
variables to be laid in memory in contiguous "storage sequences",
that are defined up to the size of the "Numeric Storage Unit".
Introducing a padding between those variables will change the results
of "storage association" operations, and will trash computations
that depend on them.
Return to contents page