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;
}