Intel® C++ Compiler 16.0 User and Reference Guide
Enforces vectorization of loops.
#pragma simd [clause[ [,] clause]...] |
clause |
Can be any of the following:
|
The simd pragma is used to guide the compiler to vectorize more loops. Vectorization using the simd pragma complements (but does not replace) the fully automatic approach.
The simd pragma can be used on a cilk_for loop. See the documentation on cilk_for for a discussion of how they are best used together.
Without explicit vectorlength() and vectorlengthfor() clauses, the compiler will choose a vectorlength using its own cost model. Misclassification of variables into private, firstprivate, lastprivate, linear, and reduction, or lack of appropriate classification of variables may cause unintended consequences such as runtime failures and/or incorrect result.
You can only specify a particular variable in at most one instance of a private, linear, or reduction clause.
If the compiler is unable to vectorize a loop, a warning will be emitted (use the assert clause to make it an error).
If the vectorizer has to stop vectorizing a loop for some reason, the fast floating-point model is used for the SIMD loop.
The vectorization performed on this loop by the simd pragma overrides any setting you may specify for options -fp-model (Linux* and OS X*) and /fp (Windows*) for this loop.
Note that the simd pragma may not affect all auto-vectorizable loops. Some of these loops do not have a way to describe the SIMD vector semantics.
The following restrictions apply to the simd pragma:
The countable loop for the simd pragma has to conform to the for-loop style of an OpenMP worksharing loop construct. Additionally, the loop control variable must be a signed integer type.
The vector values must be signed 8-, 16-, 32-, or 64-bit integers, single or double-precision floating point numbers, or single or double-precision complex numbers.
A SIMD loop may contain another loop (for, while, do-while) in it. Goto out of such inner loops are not supported. Break and continue are supported. Note that inlining can create such an inner loop, which may not be obvious at the source level.
A SIMD loop performs memory references unconditionally. Therefore, all address computations must result in valid memory addresses, even though such locations may not be accessed if the loop is executed sequentially
To disable transformations that enables more vectorization, specify the -vec -no-simd (Linux* and OS X*) or /Qvec /Qno-simd (Windows*) options.
User-mandated vectorization, also called SIMD vectorization can assert or not assert an error if a #pragma simd annotated loop fails to vectorize. By default, the simd pragma is set to noassert, and the compiler will issue a warning if the loop fails to vectorize. To direct the compiler to assert an error when the #pragma simd annotated loop fails to vectorize, add the assert clause to the simd pragma. If a simd pragma annotated loop is not vectorized by the compiler, the loop holds its serial semantics.
Example: Using the simd pragma |
---|
void add_floats(float *a, float *b, float *c, float *d, float *e, int n){ int i; #pragma simd for (i=0; i<n; i++){ a[i] = a[i] + b[i] + c[i] + d[i] + e[i]; } } |
In the example above, the function add_floats() uses too many unknown pointers for the compiler's automatic runtime independence check optimization to kick-in. The programmer can enforce the vectorization of this loop by using the simd pragma to avoid the overhead of runtime check.