このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
各ループ反復でループ本体のコピーを作成することで、for
ループを展開
coder.unroll()
は for
ループを展開します。coder.unroll
呼び出しは、展開する for
ループの直前で単独行に記述しなければなりません。
生成コード内で for
ループを生成する代わりに、ループ展開は各ループ反復で for
ループ本体のコピーを作成します。各反復で、ループ インデックスは定数になります。ループを展開するには、コード ジェネレーターは for-
ループの範囲を決定できなければなりません。
小規模で詰まったループの場合、展開によってパフォーマンスが向上します。ただし、大規模なループの場合、展開によってコード生成時間が大幅に増加し、非効率なコードが生成される可能性があります。
コード生成の範囲外では、関数 coder.unroll
は無視されます。
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_unrollflag
は for
ループを展開します。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
場合によっては、コード ジェネレーターは coder.unroll
を使用していない場合でも for
ループを展開します。たとえば、for
ループが異種混合 cell 配列または varargin
か varargout
へのインデックス付けを行う場合、コード ジェネレーターはループを展開します。ループを展開することで、コード ジェネレーターは各ループ反復のインデックスの値を決定できます。コード ジェネレーターはヒューリスティックな方法を使用して for
ループを展開するタイミングを判断します。展開が保証されていることをヒューリスティックな方法で特定できない場合や、ループの反復回数が上限を超えた場合、コード生成に失敗します。このような場合、coder.unroll
を使用してループ展開を強制的に実行できます。for ループ内の varargin または varargout のインデックスが一定でないを参照してください。
for
ループの前に coder.unroll
がない場合、コード ジェネレーターはループ展開のしきい値を使用して自動的にループを展開するかどうかを決定します。ループ反復回数がしきい値未満の場合、コード ジェネレーターはループを展開します。反復回数がしきい値以上の場合、コード ジェネレーターは for
ループを生成します。このしきい値の既定値は 5
です。このしきい値を変更して、ループ展開を微調整できます。詳細については、for ループの展開を参照してください。