Vectorization using –Mvect
Example 3.1, “Dot Product Code” and Example 3.2, “Unrolled Dot Product Code”
show the effect of code unrolling on a segment that computes a dot product.
Example 3.1. Dot Product Code Example 3.2. Unrolled Dot Product Code
REAL*4 A(100), B(100), Z
INTEGER I
DO I=1, 100
Z = Z + A(i) * B(i)
END DO
END
REAL*4 A(100), B(100), Z
INTEGER I
DO I=1, 100, 2
Z = Z + A(i) * B(i)
Z = Z + A(i+1) * B(i+1)
END DO
END
Using the
–Minfo
option, the compiler informs you when a loop is being unrolled. For example, a message similar to the following, indicating the line number, and the number of times the code is unrolled, displays when a loop is unrolled: dot:
5, Loop unrolled 5 times
Using the c:<m> and n:<m> sub-options to
–Munroll
, or using
–Mnounroll
, you can control whether
and how loops are unrolled on a file-by-file basis. Using directives or pragmas as specified in Chapter 8,
“
Using Directives and Pragmas
”
, you can precisely control whether and how a given loop is unrolled. For a detailed description of the
–Munroll
option, refer to Chapter 2, “
Using Command Line Options
”
.
Vectorization using –Mvect
The
–Mvect
option is included as part of
–fast
on all x86 and x64 targets. If your program contains computationally-intensive loops, the
–Mvect
option may be helpful. If in addition you specify
–Minfo
, and your code contains loops that can be vectorized, the compiler reports relevant information on the optimizations applied.
When a PGI compiler command is invoked with the
–Mvect
option, the vectorizer scans code searching for loops that are candidates for high-level transformations such as loop distribution, loop interchange, cache tiling, and idiom recognition (replacement of a recognizable code sequence, such as a reduction loop, with optimized code sequences or function calls). When the vectorizer finds vectorization opportunities, it internally rearranges or replaces sections of loops (the vectorizer changes the code generated; your source code’s loops are not altered). In addition to performing these loop transformations, the vectorizer produces extensive data dependence information for use by other phases of compilation and detects opportunities to use vector or packed Streaming SIMD Extensions (SSE) instructions on processors where these are supported.
The
–Mvect
option can speed up code which contains well-behaved countable loops which operate on large
REAL, REAL*4, REAL*8, INTEGER*4, COMPLEX or COMPLEX DOUBLE arrays in Fortran and their C/C++ counterparts. However, it is possible that some codes will show a decrease in performance when compiled with the
–Mvect
option due to the generation of conditionally executed code segments, inability to determine data alignment, and other code generation factors. For this reason, it is recommended that you check carefully whether particular program units or loops show improved performance when compiled with this option enabled.
Vectorization Sub-options
The vectorizer performs high-level loop transformations on countable loops. A loop is countable if the number of iterations is set only before loop execution and cannot be modified during loop execution. Some
30
Chapter 3. Optimizing & Parallelizing of the vectorizer transformations can be controlled by arguments to the
–Mvect
command line option. The following sections describe the arguments that affect the operation of the vectorizer. In addition, some of these vectorizer operations can be controlled from within code using directives and pragmas. For details on the use
of directives and pragmas, refer to Chapter 8, “
Using Directives and Pragmas
,” on page 105
.
The vectorizer performs the following operations:
• Loop interchange
• Loop splitting
• Loop fusion
• Memory-hierarchy (cache tiling) optimizations
• Generation of SSE instructions on processors where these are supported
• Generation of prefetch instructions on processors where these are supported
• Loop iteration peeling to maximize vector alignment
• Alternate code generation
By default,
–Mvect
without any sub-options is equivalent to:
-Mvect=assoc,cachesize=c where c is the actual cache size of the machine.
This enables the options for nested loop transformation and various other vectorizer options. These defaults may vary depending on the target system.
Assoc Option
The option
–Mvect=assoc
instructs the vectorizer to perform associativity conversions that can change the results of a computation due to a round-off error (
–Mvect=noassoc
disables this option). For example, a typical optimization is to change one arithmetic operation to another arithmetic operation that is mathematically correct, but can be computationally different and generate faster code. This option is provided to enable or disable this transformation, since a round-off error for such associativity conversions may produce unacceptable results.
Cachesize Option
The option
–Mvect=cachesize:n
instructs the vectorizer to tile nested loop operations assuming a data cache size of n bytes. By default, the vectorizer attempts to tile nested loop operations, such as matrix multiply, using multi-dimensional strip-mining techniques to maximize re-use of items in the data cache.
SSE Option
The option
–Mvect=sse
instructs the vectorizer to automatically generate packed SSE (Streaming SIMD
Extensions), SSE2, and prefetch instructions when vectorizable loops are encountered. SSE instructions, first introduced on Pentium III and AthlonXP processors, operate on single-precision floating-point data, and hence apply only to vectorizable loops that operate on single-precision floating-point data. SSE2 instructions, first
31