for
- ЦиклыКогда генератор кода разворачивает for
-цикл, вместо создания for
-loop в сгенерированном коде, он создает копию тела цикла для каждой итерации. Для небольших плотных циклов размотка может улучшить эффективность. Однако для больших циклов развертывание может значительно увеличить время генерации кода и сгенерировать неэффективный код.
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-loop:
z[0] = 6.0; z[1] = 7.0; z[2] = 8.0; z[3] = 9.0; z[4] = 10.0;
Для управления, когда a for
-цикл разворачивается, используйте 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
-цикл, генератор кода должен быть в состоянии определять границы for
-цикл. Для примера генерация кода прекращается для следующего кода, потому что значение n
не известно во время генерации кода.
function b = myloop(n) b = zeros(1,n); coder.unroll(); for i = 1:n b(i)=i+n; end end
-Циклы в коде MATLABЕсли for
-цикл не предшествует coder.unroll
генератор кода использует циклический порог разворачивания, чтобы определить, следует ли автоматически разворачивать цикл. Если количество итераций цикла меньше порога, генератор кода разворачивает цикл. Если количество итераций больше или равно порогу, генератор кода производит for
-цикл. Пороговое значение по умолчанию 5
. Изменяя этот порог, можно точно настроить размотку цикла. Чтобы изменить порог:
В объекте строения для автономной генерации кода (coder.CodeConfig
или coder.EmbeddedCodeConfig
), установите LoopUnrollThreshold
свойство.
В MATLAB® Coder™ приложение, на вкладке Speed, установите Loop unrolling threshold.
В отличие от coder.unroll
директива, порог применяется ко всем for
-циклы в коде MATLAB. Порог может также применяться к некоторым for
- циклы, произведенные во время генерации кода.
Для отдельного цикла, a 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
-loops, потому что продукт количества итераций двух циклов 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; }