8.2. Types of buffering

The following sections briefly describe unbuffered I/O, library buffering, system cache buffering, and ldcache.

8.2.1. Unbuffered I/O

The simplest form of buffering is none at all; this unbuffered I/O is known as raw I/O. For sufficiently large, well-formed requests, buffering is not necessary; it can add unnecessary overhead and delay. The following assign(1) command specifies unbuffered I/O:

assign -s u  ...

Use the assign command to bypass library buffering and the UNICOS system cache for all well-formed requests. The data is transferred directly between the user data area and the logical device. Requests that are not well formed use system cache.

8.2.2. Library buffering

The term library buffering refers to a buffer that the I/O library associates with a file. When a file is opened, the I/O library checks the access, form, and any attributes declared on the assign command to determine the type of processing that should be used on the file. Buffers are usually an integral part of the processing.

If the file is assigned with one of the following options, library buffering is used:

-s blocked
-s tape
-s bmx
-F spec (buffering as defined by spec)
-s cos
-s bin
-s unblocked

The -F option specifies flexible file I/O (FFIO), which uses library buffering if the specifications selected include a need for some buffering. In some cases, more than one set of buffers might be used in processing a file. For example, the -F blankx,cos option specifies two library buffers for a read of a blank compressed COS blocked file. One buffer handles the blocking and deblocking associated with the COS blocked control words and the second buffer is used as a work area to process the blank compression. In other cases (for example, -F system), no library buffering occurs.

8.2.3. System cache

The operating system or kernel uses a set of buffers in kernel memory for I/O operations. These are collectively called the system cache. The I/O library uses system calls to move data between the user memory space and the system buffer. The system cache ensures that the actual I/O to the logical device is well formed, and it tries to remember recent data in order to reduce physical I/O requests. In many cases, though, it is desirable to bypass the system cache and to perform I/O directly between the user's memory and the logical device.

On UNICOS and UNICOS/mk systems, if requests are well-formed, and the O_RAW flag is set by the libraries when the file is opened, the system cache is bypassed, and I/O is done directly between the user's memory space and the logical device.

On UNICOS systems, if the requests are not well formed, the system cache is used even if the O_RAW flag was selected at open time.

If UNICOS ldcache is present, and the request is well formed, I/O is done directly between the user's memory and ldcache even if the O_RAW bit was not selected.

The following assign(1) command options do not set the O_RAW bit, and it can be expected to use the system cache:

-s sbin
-F spec (FFIO, depends on spec)

The following assign command options set the O_RAW flag and bypass the system cache on UNICOS and UNICOS/mk systems:

-r on
-s unblocked
-s cos (or -s blocked)
-s bin
-s u
-F spec (FFIO, depends on spec)

See the Tape Subsystem User's Guide for details about the use of system caching and tapes.

For the assign -s cos , assign -s bin, and assign -s bmx commands, a library buffer ensures that the actual system calls are well formed. This is not true for the assign -s u option. If you plan to bypass the system cache, all requests go through the cache except those that are well-formed.

The assign -l buflev option controls kernel buffering. It is used by Fortran I/O, auxiliary I/O, and FFIO. The buflev argument can be any of the following values:

If this option is not set, the level of system buffering is dependent on the type of open operation being performed.

8.2.3.1. Restrictions on raw I/O

The conditions under which UNICOS/mk can perform raw I/O are different from the conditions under the UNICOS operating system. In order for raw I/O to be possible under UNICOS/mk, the starting memory address of the transfer must be aligned on a cache line boundary. This means that it must be aligned on a 0 modulus 64 byte address for Cray  T3E systems.

A C program can cause static or stack data to be aligned correctly by using the following compiler directive:

_Pragma(_CRI cache_align buff);

buff is the name of the data to be aligned.

The malloc library memory allocation functions always return aligned pointers.

In most cases where raw I/O cannot be performed due to incorrect alignment, the system will perform buffered I/O instead. The O_WELLFORMED open flag causes the ENOTWELLFORMED error to be returned.

8.2.4. Logical cache buffering

On UNICOS systems, the following elements are part of the logical device: ldcache, IOS models B, C, and D, IOS buffer memory, and cache in the disk controllers. These buffers are connected to the file system on which the file resides.

8.2.5. Default buffer sizes

The Fortran I/O library automatically selects default buffer sizes. You can override the defaults by using the assign command. The following subsections describe the default buffer sizes on various systems.

Note: One block is 4,096 bytes on UNICOS and UNICOS/mk systems.

8.2.5.1. UNICOS and UNICOS/mk default buffer sizes

On UNICOS and UNICOS/mk systems, the default buffer sizes are as follows:

Access Type 

Buffer Size

Sequential access, formatted 

The default buffer size is eight blocks.

Sequential access, unformatted 

The default buffer size is the larger of the following:

  • The large I/O size.

  • The preferred I/O block size. For more information on this, see the stat(2) man page.

  • 48 blocks.

If this results in a buffer larger than 64 blocks, then two buffers are allocated and the I/O is performed asynchronously. For more information, see the description of the cos layer in the INTRO_FFIO man page.

Direct access, formatted 

The default buffer size is the smaller of the following:

  • The record length in bytes + 1

  • Eight blocks

Direct access, unformatted 

The default buffer size is the larger of the following:

  • The record length

  • Eight blocks

The maximum default buffer size is 100 blocks. Four buffers of this size are allocated. For more information, see the description of the cachea layer in the INTRO_FFIO(3F) man page for more details.