Main Content

Optimize Loops in Generated Code

R2026b

By 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 coder.loop.Control class.

This table summarizes the loop optimization directives and specifies the function or coder.loop.Control method to use to apply each directive.

DirectiveCategoryDescriptionFunctionMethod of coder.loop.Control Class
InterchangeCache localityThis 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
ParallelizeParallelismThis 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
ReverseCache localityThis directive reverses loop iteration order, which can enable other optimization directives or improve execution behavior. coder.loop.reverse reverse
TileCache localityThis 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 JamSingle-thread optimizationThis 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
VectorizeSingle-thread optimizationThis 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);
    }
  }

See Also

Topics