Updated: 11 December 1998 |
OpenVMS Programming Concepts Manual
Previous | Contents | Index |
This chapter describes the importance and techniques of alignment for both OpenVMS VAX and OpenVMS Alpha systems.1 It contains the following subsections:
Section 24.1 describes alignment on OpenVMS VAX and OpenVMS Alpha systems.
Section 24.2 describes using compilers for alignment.
Section 24.3 describes using various tools to uncover unaligned data.
1 Reprinted from an article in the March/April 1993 issue of Digital Systems Journal, Volume 15, Number 2, titled "Alpha AXP(TM) Migration: Understanding Data Alignment on OpenVMS AXP Systems" by Eric M. LaFranchi and Kathleen D. Morse. Copyright 1993 by Cardinal Business Media, Inc., 101 Witmer Road, Horsham, PA 19044. |
Alignment is an aspect of a data item that refers to its placement in memory. The mixing of byte, word, longword, and quadword data types can lead to data that is not aligned on natural boundaries. A naturally aligned datum of size 2**N is stored in memory at a starting byte address that is a multiple of 2**N; that is, an address that has N low-order zero bits. Data is naturally aligned when its address is an integral multiple of the size of the data in bytes (for example, when the following occurs):
Data that is not aligned is referred to as unaligned. Throughout this chapter, the term aligned is used instead of naturally aligned.
Table 24-1 shows examples of common data sizes, their alignment, the number of zero bits in an aligned address for that data, and a sample aligned address in hexadecimal.
Data Size | Alignment | Zero Bits | Aligned Address Example |
---|---|---|---|
Byte | Byte | 0 | 10001, 10002, 10003, 10004 |
Word | Word | 1 | 10002, 10004, 10006, 10008 |
Longword | Longword | 2 | 10004, 10008, 1000C, 10010 |
Quadword | Quadword | 4 | 10008, 10010, 10018, 10020 |
An aligned structure has all its members aligned. An unaligned structure has one or more unaligned members. Figure 24-1 shows examples of aligned and unaligned structures.
Figure 24-1 Aligned and Unaligned Structures
To achieve optimal performance, use aligned instruction sequence references and naturally aligned data. When unaligned data is referenced, more overhead is required than when referencing aligned data. This condition is true for both OpenVMS VAX and Alpha systems. On both VAX and Alpha systems, data need not be aligned to obtain correct processing results. Alignment is a concern for performance, not program correctness. Because natural alignment is not always possible, both OpenVMS VAX and Alpha systems provide help to manage the impact of unaligned data references.
Although alignment is not required on VAX systems for stack, data, or
instruction stream references, Alpha systems require that the stack and
instructions be longword aligned.
24.1.1.1 Alignment on OpenVMS VAX (VAX Only)
On VAX systems, memory references that are not longword aligned result
in a transparent performance degradation. The full effect of unaligned
memory references is hidden by microcode, which detects the unaligned
reference and generates a microtrap to handle the alignment correction.
This fix of alignment is done entirely in microcode. Aligned
references, on the other hand, avoid the microtraps to handle fixes.
Even with this microcode fix, an unaligned reference can take up to
four times longer than an aligned reference.
24.1.1.2 Alignment on OpenVMS Alpha (Alpha Only)
On Alpha systems, you can check and correct alignment the following three ways:
Though Alpha systems do not use microcode to automatically handle unaligned references, PALcode traps the faults and corrects unaligned references as the data is processed. If you use the shorter load/store instruction sequences and your data in unaligned, then you incur an alignment fault PALcode fixup. The use of PALcode to correct alignment faults results in the slowest of the three ways to process your data.
By using directives to the compiler, you can tell your compiler to create a safe set of instructions. If it is unaligned, the compiler uses a set of unaligned load/store instructions. These unaligned load/store instructions are called safe sequences because they never generate unaligned data exceptions. Code sequences that use the unaligned load/store instructions are longer than the aligned load/store instruction sequences. By using unaligned load/store instructions and longer instruction sequences, you can obtain the desired results without incurring an alignment trap. This technique allows you to avoid the significant performance impact of a trap and subsequent data fixes.
By fixing the data yourself so that it is aligned, you can use a short instruction stream. This results in the fastest way to process your data. When aligning data, the following recommendations are suggested:
To detect unaligned reference information, you can use utilities such
as the OpenVMS Debugger and Performance and Coverage Analyzer (PCA).
You can also use the OpenVMS Alpha handler to generate optional
informational exceptions for process space references. This allows
condition handlers to track unaligned references. Alignment fault
system services allow you to enable and disable the delivery of these
informational exceptions. Section 24.3.3 discusses system services that
you can use to report both image and systemwide alignment problems.
24.2 Using Compilers for Alignment (Alpha Only)
On Alpha systems, compilers automatically align data by default. If
alignment problems are not resolved, they are at least flagged. The
following sections present how the compilers for DEC C, BLISS, DEC
Fortran, and MACRO-32 deal with alignment.
24.2.1 The DEC C Compiler (Alpha Only)
On Alpha systems, the DEC C compiler naturally aligns all explicitly declared data, including the elements of data structures. The pragmas member_alignment and nomember_alignment allow data structures to be aligned or packed (putting the next piece of data on the next byte boundary) in the same manner as the VAX C compiler. Additional pragmas of member_alignment save and member_alignment restore exist to save and restore the state of member alignment. These are useful to prevent alignment assumptions in one include file from affecting other source code. The following program examples show the use of these pragmas:
#pragma member_alignment save (1) #pragma nomember_alignment (2) struct { char byte; short word; long longword; } mystruct; #pragma member_alignment restore (3) |
The base alignment of a data structure is set to be the alignment of the largest member in the structure. If the largest element of a data structure is a longword, for example, then the base alignment of the data structure is longword alignment.
The malloc() function of the DEC C Run-Time Library
retrieves pointers that are at least quadword aligned. Because it is
the exception rather than the rule to encounter unaligned data in C
programs, the compiler assumes most data references are aligned.
Pointers, for example, are always assumed to be aligned; only data
structures declared with the pragma nomember_alignment
are assumed to contain unaligned data. If the DEC C compiler believes
the data might be unaligned, it generates the safe instruction
sequences; that is, it uses the unaligned load/store instructions.
Also, the /WARNING=ALIGNMENT compiler qualifier can be
used to turn on alignment checking by the compiler. This results in a
compiler warning for unaligned data references.
24.2.1.1 Compiler Example of Memory Structure of VAX C and DEC C
The following code examples, and Figure 24-2, and Figure 24-3 illustrate a C data structure containing byte, word, and longword data and how it would be laid out in memory by VAX C and DEC C.
struct { char byte; short word; long longword; }mystruct; |
On VAX systems, when compiled using the VAX C compiler, the previous structure has a memory layout as shown in Figure 24-2, where each piece of data begins on the next byte boundary.
Figure 24-2 Alignment Using VAX C Compiler
On Alpha systems, when compiled using the DEC C compiler, the structure is padded to achieve natural alignment, if needed, as shown in Figure 24-3.
Figure 24-3 Alignment Using DEC C Compiler
On Alpha systems, note where DEC C places some padding to align
naturally all the data structure elements. DEC C would also align the
structure itself on a longword boundary. The DEC C compiler aligns the
structure on a longword boundary because the largest element in the
structure is a longword.
24.2.2 The BLISS Compiler
On Alpha systems, the BLISS compiler provide greater control over alignment than the DEC C compiler does. The BLISS compiler also makes different assumptions about alignment.
Compaq does not ship the BLISS compiler on Alpha systems.
The Alpha BLISS compiler, like the VAX BLISS compiler, allows explicit specification of program section (PSECT) alignment.
On Alpha systems, BLISS compilers align all explicitly declared data on naturally aligned boundaries.
On Alpha systems, declared data in BLISS source code can be aligned with the ALIGN attribute, although the alignment specified cannot be greater than that for the PSECT in which the data is contained. The alignment attribute indicates a specific address boundary by means of a boundary value, N, which specifies that the binary address of the data segment must end in at least N 0s. To specify the static byte datum A to be aligned on a longword boundary, for example, the following declaration might be used:
OWN A:BYTE ALIGN(2) |
On Alpha systems, when the BLISS compiler cannot determine the base
alignment of a BLOCK, it assumes full word alignment, unless told
otherwise by a command qualifier or switch declaration. Like the DEC C
compiler, if the BLISS compilers believe that the data is unaligned,
they generate safe instruction sequences. If you specify the qualifier
/CHECK=ALIGNMENT in the BLISS command line, then
warning information is provided when they detect unaligned memory
references.
24.2.3 The DEC Fortran Compiler (Alpha Only)
On Alpha systems, the defaults for the DEC Fortran compiler emphasize compatibility and standards conformance. Normal data declarations (data declared outside of COMMON block statements) are aligned on natural boundaries by default. COMMON block statement data is not aligned by default, which conforms to the FORTRAN-77 and FORTRAN-90 standards.
The qualifier /ALIGN=(COMMONS=STANDARD) causes COMMON block data to be longword aligned. This adheres with the FORTRAN-77 and FORTRAN-90 standards, which state that the compiler is not allowed to put padding between INTEGER*4 and REAL*8 data. This can cause REAL*8 data to be unaligned. To correct this, apply the NATURAL rule; for instance, apply /ALIGN=(COMMONS=NATURAL) to get natural alignment up to quadwords and the best performance, though this is not standards conforming.
To pack COMMON block and RECORD statement data, specify /ALIGN=NONE. The qualifier /ALIGN=NONE is equivalent to /NOALIGN, /ALIGN=PACKED, or /ALIGN=(COMMON=PACKED,RECORD=PACKED). To pack just RECORD statement data, specify /ALIGN=(RECORD=PACKED).
Besides command line qualifiers, DEC Fortran provides two directives to control the alignment of RECORD statement data and COMMON block data. The CDEC$OPTIONS directive controls whether the DEC Fortran compiler naturally aligns fields in RECORD statements or data items in COMMON blocks for performance reasons, or whether the compiler packs those fields and data items together on arbitrary byte boundaries. The CDEC$OPTIONS directive, like the /ALIGN command qualifier, takes class and rule parameters. Also, the CDE$OPTIONS directive overrides the compiler option /ALIGN.
By default, the DEC Fortran compiler emits alignment warnings, but
these can be turned off by using the qualifier
/WARNINGS=NOALIGNMENT.
24.2.4 The MACRO-32 Compiler (Alpha Only)
On Alpha systems, as with the C, BLISS, and DEC Fortran languages, unaligned data references in MACRO-32 code work correctly, though they perform slower than aligned references. The MACRO-32 language provides you with direct control over alignment. There is no implicit padding for alignment done by the MACRO-32 compiler; data remains at the alignment you specify.
The MACRO-32 compiler recognizes the alignment of all locally declared data and flags all references to declared data that is unaligned. By default, the MACRO-32 compiler assumes that addresses in registers used as base pointers are longword aligned at routine entry.
For the MOVQ instruction, the compiler assumes that the base address is longword aligned, unless the compiler determines by its register-tracking logic that the address can not be longword aligned. Only longword alignment is tracked; quadword register alignment is not tracked. If you use the OpenVMS Alpha MOVQ instruction, the data must be quadword aligned, because the compiler does not translate it into unaligned loads.
External data is data that is not contained in the current source being compiled. External data is assumed to be longword aligned by the MACRO-32 compiler. The compiler detects and flags unaligned global label references. This enables you to locate external data that is not aligned.
To preserve atomicity, the compiler assumes that the data is longword aligned. Unaligned data causes a trap and voids the atomicity. Therefore, you must ensure that such data is aligned.
To fix unaligned data references, the easiest way is for you to align the data, if possible. If you cannot align the data, the data address can be moved into a register and then the register declared as unaligned. When you compile with /UNALIGNED, you tell the compiler to treat all data references as unaligned and to generate safe unaligned sequences. You can also use the .SET_REGISTERS directive, which affects data references only for the specified registers for a section of code.
The .PSECT and .ALIGN directives are supported. The compiler knows the alignment of locally declared data. The compiler makes certain assumptions about the alignment, but does allow programmer control over those assumptions. The MACRO-32 compiler provides two directives for changing the compiler's assumptions about alignment, which results in letting the compiler produce more efficient code. These two directives are as follows:
divl r0,r1 ;Compiler now thinks R1 unaligned .set_registers aligned=r1 movl 8(r1),r2 ;Compiler now treats R1 as aligned |
.symbol_alignment QUAD quad_off=4 .symbol_alignment LONG long_off=5 .symbol_alignment NONE none_off=6 movl quad_off(r0),r1 ;Assumes R0 quadword aligned movl long_off(r0),r2 ;Assumes R0 longword aligned movl none_off(r0),r3 ;No presumed alignment for R0 |
On Alpha systems, the DECmigrate for OpenVMS Alpha VAX Environment Software Translator (VEST) utility is a tool that translates binary OpenVMS VAX image files into OpenVMS Alpha image files. Image files are also called executable files. Though it is similar to compiler, VEST is for binaries instead of sources.
VEST deals with alignment in two different modes: pessimistic and optimistic. VEST is optimistic by default; but whether optimistic or pessimistic, the alignment of program counter (PC) relative data is known at translation time, and the appropriate instruction sequence can be generated.
In pessimistic mode, all non PC-relative references are treated as unaligned using the safe access sequences. In optimistic mode, the emulated VAX registers (R0--R14) are assumed to be quadword aligned upon entry to each basic block. Autoincrement and autodecrement changes to the base registers are tracked. The offset plus the base register alignment are used to determine the alignment and the appropriate access sequence is generated.
The /OPTIMIZE=NOALIGN qualifier on the VEST command tells VEST to be pessimistic; it assumes that base registers are not aligned, and should generate the safe instruction sequence. Doing this can slow execution speed by a factor of two or more, if there are no unaligned data references. On the other hand, it can result in a performance gain if there are a significant number of unaligned references, since safe sequences avoid any unaligned data traps.
There exist additional controls to preserve atomicity in longword data
that is not naturally aligned. Wherever possible, data should be
aligned in the VAX source code and the image rebuilt before translating
the image with DECmigrate. This results in better performance on both
VAX and Alpha systems.
24.3 Using Tools for Finding Unaligned Data
Tools that aid the uncovering of unaligned data include the OpenVMS Debugger, Performance and Coverage Analyzer (PCA), and eight system services. These tools are discussed in the following sections.
Previous | Next | Contents | Index |
Copyright © Compaq Computer Corporation 1998. All rights reserved. Legal |
5841PRO_063.HTML
|