Unroll for-Loops

Unrolling for-loops eliminates the loop logic by creating a separate copy of the loop body in the generated code for each iteration. Within each iteration, the loop index variable becomes a constant.

You can also force loop unrolling for individual functions by wrapping the loop header in a coder.unroll function. For more information, see coder.unroll.

Limit Copying the for-loop Body in Generated Code

To limit the number of times that you copy the body of a for-loop in generated code:

  1. Write a MATLAB® function getrand(n) that uses a for-loop to generate a vector of length n and assign random numbers to specific elements. Add a test function test_unroll. This function calls getrand(n) with n equal to values both less than and greater than the threshold for copying the for-loop in generated code.

    function [y1, y2] = test_unroll() %#codegen
    % The directive %#codegen indicates that the function
    % is intended for code generation
      % Calling getrand 8 times triggers unroll
      y1 = getrand(8);
      % Calling getrand 50 times does not trigger unroll
      y2 = getrand(50);
     
    function y = getrand(n)
      % Turn off inlining to make 
      % generated code easier to read
      coder.inline('never');
    
      % Set flag variable dounroll to repeat loop body
      % only for fewer than 10 iterations
      dounroll = n < 10;
      % Declare size, class, and complexity
      % of variable y by assignment
      y = zeros(n, 1);
      % Loop body begins
      for i = coder.unroll(1:2:n, dounroll)
          if (i > 2) && (i < n-2) 
              y(i) = rand();
          end;
      end;
      % Loop body ends
  2. Disable support for

    In the default output folder, codegen/lib/test_unroll, generate C static library code for test_unroll:

    codegen -config:lib test_unroll

    In test_unroll.c, the generated C code for getrand(8) repeats the body of the for-loop (unrolls the loop) because the number of iterations is less than 10:

    static void getrand(double y[8])
    {
      /*  Turn off inlining to make  */
      /*  generated code easier to read */
      /*  Set flag variable dounroll to repeat loop body */
      /*  only for fewer than 10 iterations */
      /*  Declare size, class, and complexity */
      /*  of variable y by assignment */
      memset(&y[0], 0, sizeof(double) << 3);
    
      /*  Loop body begins */
      y[2] = b_rand();
      y[4] = b_rand();
    
      /*  Loop body ends */
    }
    

    The generated C code for getrand(50) does not unroll the for-loop because the number of iterations is greater than 10:

    static void b_getrand(double y[50])
    {
      int i;
      int b_i;
    
      /*  Turn off inlining to make  */
      /*  generated code easier to read */
      /*  Set flag variable dounroll to repeat loop body */
      /*  only for fewer than 10 iterations */
      /*  Declare size, class, and complexity */
      /*  of variable y by assignment */
      memset(&y[0], 0, 50U * sizeof(double));
    
      /*  Loop body begins */
      for (i = 0; i < 25; i++) {
        b_i = (i << 1) + 1;
        if ((b_i > 2) && (b_i < 48)) {
          y[b_i - 1] = b_rand();
        }
      }
    

Was this topic helpful?