Optimize Loops in Generated Code
R2026bBy default, the code generator parallelizes for-loops in generated C and C++ code by using the Open Multiprocessing (OpenMP) library. See Automatic Parallelization of for-Loops in the Generated Code. You can use loop control directives to further control how the code generator implements loops in the generated code.
To address performance bottlenecks, you can use loop optimizations that target:
Cache locality. Directives that target cache locality reshape the loop for efficient data access.
Parallelism. Directives that target parallelism distribute independent iterations across CPU cores.
Single-thread optimization. Directives that target single-thread optimization increase work per instruction and reduce loop overhead.
Apply directives based on the performance bottlenecks in the generated code. To maximize impact, combine directives from different categories. Combining directives from the same category might result in smaller incremental improvements.
Choose Directives to Apply
To apply a single directive, use coder.loop functions. To combine
multiple directives in a specific order, use the methods of the class. coder.loop.Control
This table summarizes the loop optimization directives and specifies the function or
coder.loop.Control method to use to apply each directive.
| Directive | Category | Description | Function | Method of coder.loop.Control Class |
|---|---|---|---|---|
| Interchange | Cache locality | This directive improves cache performance by changing the order of the nested loops to enhance memory locality when accessing array elements. This directive enables reuse of cached data and improves execution speed. |
coder.loop.interchange
|
interchange |
| Parallelize | Parallelism | This directive improves execution speed by distributing independent loop iterations across available threads. Running iterations in parallel increases throughput for loops that sequentially access array elements. |
coder.loop.parallelize
| parallelize
|
| Reverse | Cache locality | This directive reverses loop iteration order, which can enable other optimization directives or improve execution behavior. |
coder.loop.reverse
| reverse
|
| Tile | Cache locality | This directive reduces memory access latency by partitioning the iteration space of a loop into smaller blocks, which helps data remain in cache until it is reused. |
coder.loop.tile
| tile
|
| Unroll and Jam | Single-thread optimization | This directive can eliminate nested loop overhead and improve cache reuse. It unrolls the outer loop and combines the resulting inner loop computations across iterations into a single, larger loop body. |
coder.loop.unrollAndJam
| unrollAndJam
|
| Vectorize | Single-thread optimization | This directive improves execution speed by prompting the code generator to use SIMD instructions that execute multiple loop iterations with a single CPU instruction. |
coder.loop.vectorize
| vectorize
|
Optimize Loops by Using Optimization Functions
To apply a single directive, call the loop optimization function immediately before the loop.
For example, this function uses only a single optimization directive to interchange
loopA and
loopB.
function out = applyInterchange %#codegen out = rand(10,7); coder.loop.interchange("loopA","loopB"); for loopA = 1:10 for loopB = 1:7 out(loopA,loopB) = out(loopA,loopB)+loopA; end end end
The generated code interchanges the loops.
for (loopB = 0; loopB < 7; loopB++) {
for (loopA = 0; loopA <= 8; loopA += 2) {
Optimize Loops by Using Multiple Directives
To use multiple optimization directives in your MATLAB® code, create a coder.loop.Control object in the code and
append the loop optimization directives to the object. This approach lets you apply one or
more directives to a loop while preserving their order.
Use the methods of the coder.loop.Control class to append multiple loop
optimization directives to the loop control object. Call the apply
method immediately before the target loop. For example, this function creates a loop
control object, adds the parallelize and vectorize directives to the object, and applies
the directives to the
for-loop.
function out = combineDirectives %#codegen A = rand(512,512); B = rand(512,512); C = rand(512,512); out = zeros(512,512); loopObj = coder.loop.Control; loopObj = loopObj.parallelize("j"); loopObj = loopObj.vectorize("i"); loopObj.apply; for j = 1:512 for i = 1:512 out(i,j) = A(i,j)*B(i,j)+C(i,j); end end end
The generated code parallelizes and vectorizes the loop.
for (j = 0; j < 512; j++) {
for (i = 0; i <= 510; i += 2) {
b_i = i + (j << 9);
r = _mm_loadu_pd(&A[b_i]);
r1 = _mm_loadu_pd(&B[b_i]);
r = _mm_mul_pd(r, r1);
r1 = _mm_loadu_pd(&C[b_i]);
r = _mm_add_pd(r, r1);
_mm_storeu_pd(&out[b_i], r);
}
}