exponenta event banner

coder.unroll

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

Описание

пример

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

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

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

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

пример

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

Примеры

свернуть все

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

В одном файле запишите функцию точки входа call_getrand и локальная функция getrand. getrand разворачивает for- петля, которая назначает случайные числа массиву n-by-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- тело цикла для каждой из трех итераций цикла.

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-loop, даже если вы не используете coder.unroll. Например, если for-закольцовывание индексов в гетерогенный массив ячеек или в varargin или varargoutгенератор кода разрывает цикл. Развернув цикл, генератор кода может определить значение индекса для каждой итерации цикла. Генератор кода использует эвристику, чтобы определить, когда нужно отменить for-луп. Если эвристика не определяет, что разворачивание является оправданным, или если число итераций цикла превышает предел, создание кода завершается неудачей. В этих случаях можно принудительно развернуть цикл с помощью coder.unroll. См. раздел Некондиционный индекс в varargin или varargout в for-Loop.

Представлен в R2011a