Compaq Fortran
User Manual for
OpenVMS Alpha Systems


Previous Contents Index

5.8.6 Requesting Optimized Code for a Specific Processor Generation

You can specify the types of optimized code to be generated by using the /OPTIMIZE=TUNE=keyword keywords. Regardless of the specified keyword, the generated code will run correctly on all implementations of the Alpha architecture. Tuning for a specific implementation can improve run-time performance; it is also possible that code tuned for a specific target may run slower on another target.

Specifying the correct keyword for /OPTIMIZE=TUNE=keyword for the target processor generation type usually slightly improves run-time performance. Unless you request software pipelining, the run-time performance difference for using the wrong keyword for /OPTIMIZE=TUNE=keyword (such as using /OPTIMIZE=TUNE=EV4 for an EV5 processor) is usually less than 5%. When using software pipelining (using /OPTIMIZE=LEVEL=5) with /OPTIMIZE=TUNE=keyword, the difference can be more than 5%.

The combination of the specified keyword for /OPTIMIZE=TUNE=keyword and the type of processor generation used has no effect on producing the expected correct program results.

The /OPTIMIZE=TUNE=keyword keywords are as follows:

If you omit /OPTIMIZE=TUNE=keyword, GENERIC is used.

5.8.7 Requesting Generated Code for a Specific Processor Generation

You can specify the types of instructions that will be generated for the program unit being compiled by using the /ARCHITECTURE qualifier. Unlike the /OPTIMIZE=TUNE=keyword option that helps with proper instruction scheduling, the /ARCHITECTURE qualifier specifies the type of Alpha chip instructions that can be used.

Programs compiled with the /ARCHITECTURE=GENERIC option (default) run on all Alpha processors without instruction emulation overhead.

For example, if you specify /ARCHITECTURE=EV6, the code generated will run very fast on EV6 systems, but may run slower on older Alpha processor generations. Because instructions used for the EV6 chip may be present in the program's generated code, code generated for an EV6 system may slow program execution on older Alpha processors when EV6 instructions are emulated by the OpenVMS Alpha Version 7.1 (or later) instruction emulator.

This instruction emulator allows new instructions, not implemented on the host processor chip, to execute and produce correct results. Applications using emulated instructions will run correctly, but may incur significant software emulation overhead at runtime.

The keywords used by /ARCHITECTURE=keyword are the same as those used by /OPTIMIZE=TUNE=keyword. For more information on the /ARCHITECTURE qualifier, see Section 2.3.5.

5.8.8 Arithmetic Reordering Optimizations

If you use the /ASSUME=NOACCURACY_SENSITIVE qualifier, Compaq Fortran may reorder code (based on algebraic identities) to improve performance. For example, the following expressions are mathematically equivalent but may not compute the same value using finite precision arithmetic:


X = (A + B) + C 
 
X = A + (B + C) 

The results can be slightly different from the default (ACCURACY_SENSITIVE) because of the way intermediate results are rounded. However, the NOACCURACY_SENSITIVE results are not categorically less accurate than those gained by the default. In fact, dot product summations using NOACCURACY_SENSITIVE can produce more accurate results than those using ACCURACY_SENSITIVE.

The effect of /ASSUME=NOACCURACY_SENSITIVE is important when Compaq Fortran hoists divide operations out of a loop. If NOACCURACY_SENSITIVE is in effect, the unoptimized loop becomes the optimized loop:
Unoptimized Code Optimized Code
  T = 1/V
DO I=1,N DO I=1,N
. .
. .
. .
B(I) = A(I)/V B(I) = A(I)*T
END DO END DO

The transformation in the optimized loop increases performance significantly, and loses little or no accuracy. However, it does have the potential for raising overflow or underflow arithmetic exceptions.

5.8.9 Dummy Aliasing Assumption

Some programs compiled with Compaq Fortran (or Compaq Fortran 77) may have results that differ from the results of other Fortran compilers. Such programs may be aliasing dummy arguments to each other or to a variable in a common block or shared through use association, and at least one variable access is a store.

This program behavior is prohibited in programs conforming to the Fortran 90 and Fortran 95 standards, but not by Compaq Fortran. Other versions of Fortran allow dummy aliases and check for them to ensure correct results. However, Compaq Fortran assumes that no dummy aliasing will occur, and it can ignore potential data dependencies from this source in favor of faster execution.

The Compaq Fortran default is safe for programs conforming to the Fortran 90 and Fortran 95 standards. It will improve performance of these programs, because the standard prohibits such programs from passing overlapped variables or arrays as actual arguments if either is assigned in the execution of the program unit.

The /ASSUME=DUMMY_ALIASES qualifier allows dummy aliasing. It ensures correct results by assuming the exact order of the references to dummy and common variables is required. Program units taking advantage of this behavior can produce inaccurate results if compiled with /ASSUME=NODUMMY_ALIASES.

Example 5-3 is taken from the DAXPY routine in the Fortran-77 version of the Basic Linear Algebra Subroutines (BLAS).

Example 5-3 Using the /ASSUME =DUMMY_ALIASES Qualifier

      SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY) 
 
!     Constant times a vector plus a vector. 
!     uses unrolled loops for increments equal to 1. 
 
      DOUBLE PRECISION DX(1), DY(1), DA 
      INTEGER I,INCX,INCY,IX,IY,M,MP1,N 
! 
      IF (N.LE.0) RETURN 
      IF (DA.EQ.0.0) RETURN 
      IF (INCX.EQ.1.AND.INCY.EQ.1) GOTO 20 
 
!     Code for unequal increments or equal increments 
!     not equal to 1. 
      . 
      . 
      . 
      RETURN 
!     Code for both increments equal to 1. 
!     Clean-up loop 
 
 20   M = MOD(N,4) 
      IF (M.EQ.0) GOTO 40 
      DO I=1,M 
          DY(I) = DY(I) + DA*DX(I) 
      END DO 
      IF (N.LT.4) RETURN 
 40   MP1 = M + 1 
      DO I = MP1, N, 4 
          DY(I) = DY(I) + DA*DX(I) 
          DY(I + 1) = DY(I + 1) + DA*DX(I + 1) 
          DY(I + 2) = DY(I + 2) + DA*DX(I + 2) 
          DY(I + 3) = DY(I + 3) + DA*DX(I + 3) 
      END DO 
      RETURN 
      END SUBROUTINE 

The second DO loop contains assignments to DY. If DY is overlapped with DA, any of the assignments to DY might give DA a new value, and this overlap would affect the results. If this overlap is desired, then DA must be fetched from memory each time it is referenced. The repetitious fetching of DA degrades performance.

Linking Routines with Opposite Settings

You can link routines compiled with the /ASSUME=DUMMY_ALIASES qualifier to routines compiled with /ASSUME=NODUMMY_ALIASES. For example, if only one routine is called with dummy aliases, you can use /ASSUME=DUMMY_ALIASES when compiling that routine, and compile all the other routines with /ASSUME=NODUMMY_ALIASES to gain the performance value of that qualifier.

Programs calling DAXPY with DA overlapping DY do not conform to the FORTRAN-77, Fortran 90, and Fortran 95 standards. However, they are supported if /ASSUME=DUMMY_ALIASES was used to compile the DAXPY routine.


Chapter 6
Compaq Fortran Input/Output

This chapter describes Compaq Fortran input/output (I/O) as implemented for Compaq Fortran. It also provides information about Compaq Fortran I/O in relation to the OpenVMS Record Management Services (RMS) and Run-Time Library (RTL).

The following topics are addressed in this chapter:

Compaq Fortran assumes all unformatted data files will be in the same native little endian numeric formats used in memory. If you need to read or write unformatted numeric data (on disk) that has a different numeric format than that used in memory, see Chapter 9.

You can use Compaq Fortran I/O statements to communicate between processes on either the same computer or different computers.

For More Information:

6.1 Logical I/O Units

In Compaq Fortran, a logical unit is a channel through which data transfer occurs between the program and a device or file. You identify each logical unit with a logical unit number, which can be any nonnegative integer from 0 to a maximum value of 2,147,483,647 (2**31--1).

For example, the following READ statement uses logical unit number 2:


READ (2,100) I,X,Y 

This READ statement specifies that data is to be entered from the device or file corresponding to logical unit 2, in the format specified by the FORMAT statement labeled 100.

When opening a file, use the UNIT specifier to indicate the unit number. You can use the LIB$GET_LUN library routine to return a logical unit number not currently in use by your program. If you intend to use LIB$GET_LUN, avoid using logical unit numbers (UNIT) 100 to 119 (reserved for LIB$GET_LUN).

Compaq Fortran programs are inherently device-independent. The association between the logical unit number and the physical file can occur at run-time. Instead of changing the logical unit numbers specified in the source program, you can change this association at run time to match the needs of the program and the available resources. For example, before running the program, a command procedure can set the appropriate logical name or allow the terminal user to type a directory, file name, or both.

Use the same logical unit number specified in the OPEN statement for other I/O statements to be applied to the opened file, such as READ and WRITE.

The OPEN statement connects a unit number with an external file and allows you to explicitly specify file attributes and run-time options using OPEN statement specifiers (all files except internal files are called external files).

ACCEPT, TYPE, and PRINT statements do not refer explicitly to a logical unit (a file or device) from which or to which data is to be transferred; they refer implicitly to a default preconnected logical unit. The ACCEPT statement is normally preconnected to the default input device, and the TYPE and PRINT statements are normally preconnected to the default output device. These defaults can be overridden with appropriate logical name assignments (see Section 6.5.1.2).

READ, WRITE, and REWRITE statements refer explicitly to a specified logical unit from which or to which data is to be transferred. However, to use a preconnected device for READ (SYS$INPUT) and WRITE (SYS$OUTPUT), specify the unit number as an asterisk (*).

Certain unit numbers are preconnected to OpenVMS standard devices. Unit number 5 is associated with SYS$INPUT and unit 6 with SYS$OUTPUT. At run time, if units 5 and 6 are specified by a record I/O statement (such as READ or WRITE) without having been explicitly opened by an OPEN statement, Compaq Fortran implicitly opens units 5 and 6 and associates them with their respective operating system standard I/O files.

For More Information:

On the OPEN statement and preconnected files, see Section 6.5.

6.2 Types of I/O Statements

Table 6-1 lists the Compaq Fortran I/O statements.

Table 6-1 Summary of I/O Statements
Category and Statement Name Description
File Connection  
OPEN Connects a unit number with an external file and specifies file connection characteristics.
CLOSE Disconnects a unit number from an external file.
File Inquiry  
INQUIRE Returns information about a named file, a connection to a unit, or the length of an output item list.
Record Position  
BACKSPACE Moves the record position to the beginning of the previous record (sequential access only).
ENDFILE Writes an end-of-file marker after the current record (sequential access only).
REWIND Sets the record position to the beginning of the file (sequential access only).
Record Input  
READ Transfers data from an external file record or an internal file to internal storage.
Record Output  
WRITE Transfers data from internal storage to an external file record or to an internal file.
PRINT Transfers data from internal storage to SYS$OUTPUT (standard output device). Unlike WRITE, PRINT only provides formatted sequential output and does not specify a unit number.
Compaq Fortran Extensions  
ACCEPT Reads input from SYS$INPUT. Unlike READ, ACCEPT only provides formatted sequential output and does not specify a unit number.
DELETE Marks a record at the current record position in a relative file as deleted (direct access only).
REWRITE Transfers data from internal storage to an external file record at the current record position. Certain restrictions apply.
UNLOCK Releases a lock held on the current record when file sharing was requested when the file was opened (see Section 6.8.2).
TYPE Writes record output to SYS$OUTPUT (same as PRINT).
DEFINE FILE Specifies file characteristics for a direct access relative file and connects the unit number to the file (like an OPEN statement). Provided for compatibility with compilers older than FORTRAN-77.
FIND Changes the record position in a direct access file. Provided for compatibility with compilers older than FORTRAN-77.

In addition to the READ, WRITE, REWRITE, TYPE, and PRINT statements, other I/O record-related statements are limited to a specific file organization. For instance:

The file-related statements (OPEN, INQUIRE, and CLOSE) apply to any relative or sequential file.

6.3 Forms of I/O Statements

Each type of record I/O statement can be coded in a variety of forms. The form you select depends on the nature of your data and how you want it treated. When opening a file, specify the form using the FORM specifier. The following are the forms of I/O statements:

Formatted, list-directed, and namelist I/O forms require translation of data from internal (binary) form within a program to external (readable character) form in the records. Consider using unformatted I/O for the following reasons:

To write data to a file using formatted, list-directed, or namelist I/O statements, specify FORM='FORMATTED' when opening the file. To write data to a file using unformatted I/O statements, specify FORM='UNFORMATTED' when opening the file.

Data written using formatted, list-directed, or namelist I/O statements is referred to as formatted data; data written using unformatted I/O statements is referred to as unformatted data.

When reading data from a file, you should use the same I/O statement form that was used to write the data to the file. For instance, if data was written to a file with a formatted I/O statement, you should read data from that file with a formatted I/O statement.

Although I/O statement form is usually the same for reading and writing data in a file, a program can read a file containing unformatted data (using unformatted input) and write it to a separate file containing formatted data (using formatted output). Similarly, a program can read a file containing formatted data and write it to a different file containing unformatted data.

As described in Section 6.8.2, you can access records in any sequential, relative, or indexed file using sequential access. For relative files and fixed-length sequential files, you can also access records using direct access. For indexed files, you can use keyed access.

Table 6-2 shows the main record I/O statements, by category, that can be used in Compaq Fortran programs.

Table 6-2 Available I/O Statements and Record I/O Forms
File Type, Access, and I/O Form Available Statements
External file, sequential access
Formatted
List-Directed
Namelist
Unformatted
READ, WRITE, PRINT, ACCEPT 1, TYPE 1, and REWRITE 1
READ, WRITE, PRINT, ACCEPT 1, TYPE 1, and REWRITE 1
READ, WRITE, PRINT, ACCEPT 1, TYPE 1, and REWRITE 1
READ, WRITE, and REWRITE 1
External file, direct access
Formatted
Unformatted
READ, WRITE, and REWRITE 1
READ, WRITE, and REWRITE 1
External file, keyed access
Formatted
Unformatted
READ, WRITE, and REWRITE 1
READ, WRITE, and REWRITE 1
Internal file 2
Formatted
List-Directed
Unformatted
READ, WRITE
READ, WRITE
None


1This statement is a Compaq extension to the Fortran 90 and Fortran 95 standards.
2An internal file is a way to reference character data in a buffer using sequential access (see Section 6.4.2).

6.4 Types of Files and File Characteristics

This section discusses file organization, internal and scratch files, record type, record length, and other file characteristics.

6.4.1 File Organizations

File organization refers to the way records are physically arranged on a storage device.

The default file organization is always ORGANIZATION='SEQUENTIAL' for an OPEN statement.

Compaq Fortran supports three kinds of file organizations: sequential, relative, and indexed sequential. The organization of a file is specified by means of the ORGANIZATION specifier in the OPEN statement.

You must store relative files on a disk device. You can store sequential files on magnetic tape or disk devices, and can use other peripheral devices, such as terminals and line printers, as sequential files.

File characteristics, including the file organization and record type, are stored by RMS in the disk file header and can be obtained by using the INQUIRE statement. You can also view the organization of a file using the DCL command DIRECTORY/FULL.

For more information on the INQUIRE statement, see Section 6.6 and the Compaq Fortran Language Reference Manual.

Sequential Organization

A sequentially organized file consists of records arranged in the sequence in which they are written to the file (the first record written is the first record in the file, the second record written is the second record in the file, and so on). As a result, records can be added only at the end of the file.

Sequential files are usually read sequentially, starting with the first record in the file. Sequential files stored on disk with a fixed-length record type can also be accessed by relative record number (direct access).

Relative Organization

Within a relative file are numbered positions, called cells. These cells are of fixed equal length and are consecutively numbered from 1 to n, where 1 is the first cell, and n is the last available cell in the file. Each cell either contains a single record or is empty.

Records in a relative file are accessed according to cell number. A cell number is a record's relative record number (its location relative to the beginning of the file). By specifying relative record numbers, you can directly retrieve, add, or delete records regardless of their locations (direct access).

Relative files allow you to use direct access and detect when a record has been deleted.

When creating a relative file, specify the RECL value to determine the size of the fixed-length cells. Within the cells, you can store variable-length records as long as their size does not exceed the cell size.

Indexed Files

An indexed file consists of two or more separate sections: one section contains the data records and the other sections contain indexes. When an indexed file is created, each index is associated with a specification defining a field within each record, called a key field or simply key. A record in an indexed file must contain at least one key, called the primary key, which determines the location of the records within the body of the file.

The keys of all records are collected to form one or more structured indexes, through which records are always accessed. The structure of the indexes allows a program to access records in an indexed file either randomly (keyed access) or sequentially (sequential access). With keyed access, you specify a particular key value. With sequential access, you retrieve records with increasing or decreasing key values. You can mix keyed access and sequential access.

Indexed files are supported only on disk devices. When creating an indexed file, specify the RECL value.

For more information on indexed files, see Chapter 12.


Previous Next Contents Index