coder.unroll

Разблокируйте for-loop путем создания копии тела цикла для каждой итерации цикла

Описание

пример

coder.unroll() разворачивает for-цикл. coder.unroll вызов должен быть на линии сам по себе, непосредственно предшествующей for-цикл, который он разворачивает.

Вместо создания for-loop в сгенерированном коде, цикл развертывания создает копию for-loop тело для каждой итерации цикла. В каждой итерации индекс цикла становится постоянным. Чтобы развернуть цикл, генератор кода должен быть в состоянии определить границы for-цикл.

Для небольших плотных циклов размотка может улучшить эффективность. Однако для больших циклов развертывание может значительно увеличить время генерации кода и сгенерировать неэффективный код.

coder.unroll игнорируется вне генерации кода.

пример

coder.unroll(flag) разворачивает for-цикл, если flag является true. flag оценивается во время генерации кода. coder.unroll вызов должен быть на линии сам по себе, непосредственно предшествующей for-цикл, который он разворачивает.

Примеры

свернуть все

Создание копий for-цикл тело в сгенерированном коде, использование coder.unroll.

В одном файле запишите функцию точки входа call_getrand и локальную функцию getrand. getrand разворачивает for-цикл, который присваивает случайные числа массиву n на 1. call_getrand вызовы getrand со значением 3.

function z = call_getrand 
%#codegen
z = getrand(3);
end

function y = getrand(n)
coder.inline('never');
y = zeros(n, 1);
coder.unroll();
for i = 1:n
    y(i) = rand();
end
end

Сгенерируйте статическую библиотеку.

codegen -config:lib call_getrand -report

В сгенерированном коде генератор кода производит копию for-loop тело для каждой из трех итераций цикла.

static void getrand(double y[3])
{
  y[0] = b_rand();
  y[1] = b_rand();
  y[2] = b_rand();
}

Цикл управления при помощи coder.unroll с flag аргумент.

В одном файле запишите функцию точки входа call_getrand_unrollflag и локальную функцию getrand_unrollflag. Когда количество итераций цикла меньше 10, getrand_unrollflag разворачивает for-цикл. call_getrand вызовы getrand со значением 50.

function z = call_getrand_unrollflag
%#codegen
z = getrand_unrollflag(50);
end

function y = getrand_unrollflag(n)
coder.inline('never');
unrollflag = n < 10;
y = zeros(n, 1);
coder.unroll(unrollflag)
for i = 1:n
    y(i) = rand();
end
end

Сгенерируйте статическую библиотеку.

codegen -config:lib call_getrand_unrollflag -report
static void getrand_unrollflag(double y[50])
{
  int i;
  for (i = 0; i < 50; i++) {
    y[i] = b_rand();
  }
}

Количество итераций не менее 10. Поэтому генератор кода не разворачивает for-цикл. Он создает for-цикл в сгенерированном коде.

  • function z = call_getrand 
    %#codegen
    z = getrand(3);
    end
    
    function y = getrand(n)
    coder.inline('never');
    y = zeros(n, 1);
    for i = coder.unroll(1:n)
        y(i) = rand();
    end
    end
  • function z = call_getrand_unrollflag
    %#codegen
    z = getrand_unrollflag(50);
    end
    
    function y = getrand_unrollflag(n)
    coder.inline('never');
    unrollflag = n < 10;
    y = zeros(n, 1);
    for i = coder.unroll(1:n, unrollflag)
        y(i) = rand();
    end
    end

Входные параметры

свернуть все

Когда flag является trueгенератор кода разворачивает for-цикл. Когда flag является falseгенератор кода производит for-цикл в сгенерированном коде. flag оценивается во время генерации кода.

Совет

  • Иногда генератор кода разворачивает for-цикл, хотя вы не используете coder.unroll. Для примера, если a for-цикл индексы в гетерогенный массив ячеек или в varargin или varargoutгенератор кода разворачивает цикл. Путем разворачивания цикла генератор кода может определить значение индекса для каждой итерации цикла. Генератор кода использует эвристику, чтобы определить, когда разворачивать for-цикл. Если эвристика не может идентифицировать, что развертывание оправдано, или если количество итераций цикла превышает предел, генерация кода прекращает работать. В этих случаях можно принудительно разворачивать цикл при помощи coder.unroll. Смотрите Non-Constant Index в varargin или varargout в цикле for-Loop.

Введенный в R2011a