exponenta event banner

Развернуть for- Петли

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

Принудительное разворачивание цикла с помощью coder.unroll

Генератор кода использует эвристику, чтобы определить, когда нужно отменить for-луп. Для принудительного разворачивания цикла используйте coder.unroll. Это влияет только на for цикл, который сразу после coder.unroll. Например:

function z = call_myloop()
%#codegen
z = myloop(5);
end

function b = myloop(n)
b = zeros(1,n);
coder.unroll();
for i = 1:n
    b(i)=i+n;
end
end

Вот сгенерированный код для цикла for:

  z[0] = 6.0;
  z[1] = 7.0;
  z[2] = 8.0;
  z[3] = 9.0;
  z[4] = 10.0;

Управление при for-loop не развернут, используйте coder.unroll flag аргумент. Например, разматывать цикл можно только в том случае, если число итераций меньше 10.

function z = call_myloop()
%#codegen
z = myloop(5);
end

function b = myloop(n)
unroll_flag = n < 10;
b = zeros(1,n);
coder.unroll(unroll_flag);
for i = 1:n
    b(i)=i+n;
end
end

Распаковка for-loop, генератор кода должен иметь возможность определять границы for-луп. Например, не удалось создать код для следующего кода, поскольку значение n неизвестен во время генерации кода.

function b = myloop(n)
b = zeros(1,n);
coder.unroll();
for i = 1:n
    b(i)=i+n;
end
end

Установить порог отмены цикла для всех for- циклы в коде MATLAB

Если for-loop не предшествует coder.unrollгенератор кода использует порог разматывания цикла, чтобы определить, следует ли автоматически разматывать цикл. Если число итераций цикла меньше порогового значения, генератор кода разворачивает цикл. Если число итераций больше или равно пороговому значению, генератор кода создает for-луп. Значение порога по умолчанию: 5. Изменяя это пороговое значение, можно точно настроить разворачивание цикла. Для изменения порогового значения:

  • В объекте конфигурации для создания автономного кода (coder.CodeConfig или coder.EmbeddedCodeConfig), установите LoopUnrollThreshold собственность.

  • В приложении MATLAB ® Coder™ на вкладке Скорость установите пороговое значение Размыкания цикла.

В отличие от coder.unroll директива, порог применяется ко всем for-циклы в коде MATLAB. Порог также может применяться к некоторым for- циклы, создаваемые во время генерации кода.

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

Разворачивание простого for- Петли

Рассмотрим эту функцию:

function [x,y] = call_myloops()
%#codegen
x = myloop1(5);
y = myloop2(5);
end

function b = myloop1(n)
b = zeros(1,n);
for i = 1:n
    b(i)=i+n;
end
end

function b = myloop2(n)
b = zeros(1,n);
for i = 1:n
    b(i)=i*n;
end
end

Установка значения порога разгрузки цикла в 6, а затем создайте статическую библиотеку, запустите:

cfg = coder.CodeConfig;
cfg.LoopUnrollThreshold = 6;
codegen call_myloops -config cfg

Это созданный код для for-контуры. Генератор кода распаковал оба for-контуры.

  x[0] = 6.0;
  y[0] = 5.0;
  x[1] = 7.0;
  y[1] = 10.0;
  x[2] = 8.0;
  y[2] = 15.0;
  x[3] = 9.0;
  y[3] = 20.0;
  x[4] = 10.0;
  y[4] = 25.0;

Разворачивать вложенные for- Петли

Предположим, что код MATLAB имеет два вложенных for-контуры.

  • Если число итераций внутреннего цикла меньше порогового значения, генератор кода сначала разворачивает внутренний цикл. Впоследствии, если произведение числа итераций двух циклов также меньше порогового значения, генератор кода разворачивает внешний цикл. В противном случае генератор кода создает внешний for-луп.

  • Если число итераций внутреннего цикла равно или больше порогового значения, генератор кода производит оба for-контуры.

Это поведение обобщено на несколько вложенных for-контуры.

Рассмотрим функцию nestedloops_1 с двумя вложенными for-контуры:

function y = nestedloops_1
%#codegen
y = zeros(2,2);
for i = 1:2
    for j = 1:2
        y(i,j) = i+j;
    end
end
end

Создать код для nestedloops_1 с пороговым значением разгрузки цикла, установленным в значение по умолчанию 5. Вот созданный код для for-контуры. Генератор кода распаковал оба for- петли, поскольку произведение числа итераций двух петель 4, что меньше порогового значения.

  y[0] = 2.0;
  y[2] = 3.0;
  y[1] = 3.0;
  y[3] = 4.0;

Теперь создайте код для функции nestedloops_2 с пороговым значением разгрузки цикла, установленным в значение по умолчанию 5.

function y = nestedloops_2
%#codegen
y = zeros(3,2);
for i = 1:3
    for j = 1:2
        y(i,j) = i+j;
    end
end
end

Число итераций внутреннего цикла меньше порогового значения. Генератор кода разрывает внутренний контур. Но произведение числа итераций двух циклов 6, что больше порогового значения. Следовательно, генератор кода создает код для внешнего for-луп. Вот созданный код для for-контуры.

  for (i = 0; i < 3; i++) {
    y[i] = (double)i + 2.0;
    y[i + 3] = ((double)i + 1.0) + 2.0;
  }

См. также

Связанные темы