106 lines
2.9 KiB
ReStructuredText
106 lines
2.9 KiB
ReStructuredText
|
.. title:: clang-tidy - altera-unroll-loops
|
||
|
|
||
|
altera-unroll-loops
|
||
|
===================
|
||
|
|
||
|
Finds inner loops that have not been unrolled, as well as fully unrolled loops
|
||
|
with unknown loop bounds or a large number of iterations.
|
||
|
|
||
|
Unrolling inner loops could improve the performance of OpenCL kernels. However,
|
||
|
if they have unknown loop bounds or a large number of iterations, they cannot
|
||
|
be fully unrolled, and should be partially unrolled.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
- This check is unable to determine the number of iterations in a ``while`` or
|
||
|
``do..while`` loop; hence if such a loop is fully unrolled, a note is emitted
|
||
|
advising the user to partially unroll instead.
|
||
|
|
||
|
- In ``for`` loops, our check only works with simple arithmetic increments (
|
||
|
``+``, ``-``, ``*``, ``/``). For all other increments, partial unrolling is
|
||
|
advised.
|
||
|
|
||
|
- Depending on the exit condition, the calculations for determining if the
|
||
|
number of iterations is large may be off by 1. This should not be an issue
|
||
|
since the cut-off is generally arbitrary.
|
||
|
|
||
|
Based on the `Altera SDK for OpenCL: Best Practices Guide
|
||
|
<https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf>`_.
|
||
|
|
||
|
.. code-block:: c++
|
||
|
|
||
|
for (int i = 0; i < 10; i++) { // ok: outer loops should not be unrolled
|
||
|
int j = 0;
|
||
|
do { // warning: this inner do..while loop should be unrolled
|
||
|
j++;
|
||
|
} while (j < 15);
|
||
|
|
||
|
int k = 0;
|
||
|
#pragma unroll
|
||
|
while (k < 20) { // ok: this inner loop is already unrolled
|
||
|
k++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int A[1000];
|
||
|
#pragma unroll
|
||
|
// warning: this loop is large and should be partially unrolled
|
||
|
for (int a : A) {
|
||
|
printf("%d", a);
|
||
|
}
|
||
|
|
||
|
#pragma unroll 5
|
||
|
// ok: this loop is large, but is partially unrolled
|
||
|
for (int a : A) {
|
||
|
printf("%d", a);
|
||
|
}
|
||
|
|
||
|
#pragma unroll
|
||
|
// warning: this loop is large and should be partially unrolled
|
||
|
for (int i = 0; i < 1000; ++i) {
|
||
|
printf("%d", i);
|
||
|
}
|
||
|
|
||
|
#pragma unroll 5
|
||
|
// ok: this loop is large, but is partially unrolled
|
||
|
for (int i = 0; i < 1000; ++i) {
|
||
|
printf("%d", i);
|
||
|
}
|
||
|
|
||
|
#pragma unroll
|
||
|
// warning: << operator not supported, recommend partial unrolling
|
||
|
for (int i = 0; i < 1000; i<<1) {
|
||
|
printf("%d", i);
|
||
|
}
|
||
|
|
||
|
std::vector<int> someVector (100, 0);
|
||
|
int i = 0;
|
||
|
#pragma unroll
|
||
|
// note: loop may be large, recommend partial unrolling
|
||
|
while (i < someVector.size()) {
|
||
|
someVector[i]++;
|
||
|
}
|
||
|
|
||
|
#pragma unroll
|
||
|
// note: loop may be large, recommend partial unrolling
|
||
|
while (true) {
|
||
|
printf("In loop");
|
||
|
}
|
||
|
|
||
|
#pragma unroll 5
|
||
|
// ok: loop may be large, but is partially unrolled
|
||
|
while (i < someVector.size()) {
|
||
|
someVector[i]++;
|
||
|
}
|
||
|
|
||
|
Options
|
||
|
-------
|
||
|
|
||
|
.. option:: MaxLoopIterations
|
||
|
|
||
|
Defines the maximum number of loop iterations that a fully unrolled loop
|
||
|
can have. By default, it is set to `100`.
|
||
|
|
||
|
In practice, this refers to the integer value of the upper bound
|
||
|
within the loop statement's condition expression.
|