最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

coder.unroll

各ループ反復でループ本体のコピーを作成することで、for ループを展開

説明

coder.unroll()for ループを展開します。coder.unroll 呼び出しは、展開する for ループの直前で単独行に記述しなければなりません。

生成コード内で for ループを生成する代わりに、ループ展開は各ループ反復で for ループ本体のコピーを作成します。各反復で、ループ インデックスは定数になります。ループを展開するには、コード ジェネレーターは for- ループの範囲を決定できなければなりません。

小規模で詰まったループの場合、展開によってパフォーマンスが向上します。ただし、大規模なループの場合、展開によってコード生成時間が大幅に増加し、非効率なコードが生成される可能性があります。

コード生成の範囲外では、関数 coder.unroll は無視されます。

coder.unroll(flag) は、flagtrue である場合に for ループを展開します。flag はコード生成時に評価されます。coder.unroll 呼び出しは、展開する for ループの直前で単独行に記述しなければなりません。

for ループの展開

生成コード内で for ループ本体のコピーを作成するには、coder.unroll を使用します。

1 つのファイルで、エントリポイント関数 call_getrand とローカル関数 getrand を記述します。getrand は、n 行 1 列の配列に乱数を割り当てる for ループを展開します。call_getrand は値 3 をもつ getrand を呼び出します。

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

生成されたコードで、コード ジェネレーターは 3 つのループ反復それぞれに対して for ループ本体のコピーを作成します。

static void getrand(double y[3])
{
  y[0] = b_rand();
  y[1] = b_rand();
  y[2] = b_rand();
}

フラグによる for ループ展開の制御

flag 引数を指定した coder.unroll を使用して、ループ展開を制御します。

1 つのファイルで、エントリポイント関数 call_getrand_unrollflag とローカル関数 getrand_unrollflag を記述します。ループ反復回数が 10 回未満の場合、getrand_unrollflagfor ループを展開します。call_getrand は値 50 をもつ getrand を呼び出します。

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

反復回数は 10 回未満ではありません。したがって、コード ジェネレーターは for ループを展開しません。生成コード内で for ループを生成します。

static void getrand_unrollflag(double y[50])
{
  int i;
  for (i = 0; i < 50; i++) {
    y[i] = b_rand();
  }
}

レガシ構文を使用した 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

レガシ構文を使用した for ループ展開の制御

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

入力引数

すべて折りたたむ

flagtrue である場合、コード ジェネレーターは for ループを展開します。flagfalse である場合、コード ジェネレーターは生成コード内で for ループを生成します。flag はコード生成時に評価されます。

ヒント

  • 場合によっては、コード ジェネレーターは coder.unroll を使用していない場合でも for ループを展開します。たとえば、for ループが異種混合 cell 配列または vararginvarargout へのインデックス付けを行う場合、コード ジェネレーターはループを展開します。ループを展開することで、コード ジェネレーターは各ループ反復のインデックスの値を決定できます。コード ジェネレーターはヒューリスティックな方法を使用して for ループを展開するタイミングを判断します。展開が保証されていることをヒューリスティックな方法で特定できない場合や、ループの反復回数が上限を超えた場合、コード生成に失敗します。このような場合、coder.unroll を使用してループ展開を強制的に実行できます。for ループ内の varargin または varargout のインデックスが一定でないを参照してください。

R2011a で導入