unroll

Date:

06-19-2023

NAME

unroll, nounroll - control unrolling for individual loops

SYNOPSIS

!DIR$ UNROLL [ n ]
!DIR$ NOUNROLL

DESCRIPTION

Scope: Local

The unroll directive allows the user to control unrolling for individual loops or to specify no unrolling of a loop. Loop unrolling can improve program performance by revealing cross-iteration memory optimization opportunities such as read-after-write and read-after-read. The effects of loop unrolling also include:

  • Improved loop scheduling by increasing basic block size

  • Reduced loop overhead

  • Improved chances for cache hits

The nounrolldirective disables loop unrolling for the next loop and does not accept the integer argument n. The nounroll directive is equivalent to the unroll 0 and unroll 1 directives.

The n argument applies only to the unroll directive and specifies no loop unrolling (n = 0 or 1) or the total number of loop body copies to be generated (2 <=*n* <= 63).

If you do not specify a value for n, the compiler will determine the number of copies to generate based on the number of statements in the loop nest.

Note: The compiler cannot always safely unroll non-innermost loops due to data dependencies. In these cases, the directive is ignored.

The unroll directive can be used only on loops with iteration counts that can be calculated before entering the loop. If unroll is specified on a loop that is not the innermost loop in a loop nest, the inner loops must be nested perfectly. That is, all loops in the nest can contain only one loop, and the innermost loop can contain work.

EXAMPLES

Example 1: Unrolling Outer Loops

In the following Fortran example, assume that the outer loop of the following nest will be unrolled by 2:

!DIR$ UNROLL 2
                     DO I = 1, 10
                             DO J = 1,100
                                             A(J,I) = B(J,I) + 1
                             END DO
                     END DO

With outer loop unrolling, the compiler produces the following nest, in which the two bodies of the inner loop are adjacent:

DO I = 1, 10, 2
             DO J = 1,100
                             A(J,I) = B(J,I) + 1
             END DO
             DO J = 1,100
                             A(J,I+1) = B(J,I+1) + 1
             END DO
END DO

The compiler jams, or fuses, the inner two loop bodies together, producing the following nest:

DO I = 1, 10, 2
             DO J = 1,100
                             A(J,I) = B(J,I) + 1
                             A(J,I+1) = B(J,I+1) + 1
             END DO
END DO

Example 2: Illegal Unrolling of Outer Loops

Outer loop unrolling is not always legal because the transformation can change the semantics of the original program. For example, unrolling the following loop nest on the outer loop would change the program semantics because of the dependency betweenA(…,I) and A(…,I+1):

!DIR$ UNROLL 2
                     DO I = 1, 10
                             DO J = 1,100
                                                             A(J,I) = A(J-1,I+1) + 1
                             END DO
                     END DO

SEE ALSO

intro_directives(7)