for
- циклыКогда генератор кода разворачивает for
- цикл, вместо того, чтобы произвести 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
- цикл будет развернут, используйте
аргумент 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
for
- циклы в коде MATLABЕсли for
- циклу не предшествует coder.unroll
, генератор кода использует порог развертывания цикла, чтобы определить, развернуть ли автоматически цикл. Если количество итераций цикла является меньше, чем порог, генератор кода разворачивает цикл. Если количество итераций больше, чем или равно порогу, генератор кода производит for
- цикл. Значением по умолчанию порога является 5
. Путем изменения этого порога можно подстроить развертывание цикла. Изменить порог:
В объекте настройки для автономной генерации кода (coder.CodeConfig
или coder.EmbeddedCodeConfig
), устанавливает свойство LoopUnrollThreshold
.
В приложении MATLAB® Coder™, на вкладке Speed, устанавливает Loop unrolling threshold.
В отличие от директивы 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; }