生成されたコード内での重複関数の回避
問題
生成されるコードには、関数シグネチャの変更などわずかな違いがあるだけの、同じ関数についての複数の重複コピーが含まれます。たとえば、生成されたコードに foo
および b_foo
と呼ばれる関数が含まれている場合があります。重複関数は生成されたコードの解析と管理をより難しくする可能性があります。
原因
生成されるコード内での重複関数は、関数の特殊化の結果です。コード ジェネレーターは、さまざまな呼び出しサイトで関数の次の項目が異なるということを検出すると、関数を特殊化します。
入力変数または出力変数の数。
入力変数または出力変数の型。
入力変数または出力変数のサイズ。
入力変数の値。
C/C++ 関数には MATLAB® 関数と同じような柔軟性がないため、場合によっては、こうした特殊化は生成された C/C++ コードに必要です。別の例として、コード ジェネレーターは生成されたコードを最適化する目的で、あるいは情報不足を要因として、関数を特殊化します。
解決法
特定の状況では、MATLAB コードを変更して、重複関数の生成を回避することもできます。
コード生成レポートを使用した重複関数の特定
コード生成レポート、Simulink®、または MATLAB 関数レポートを検証することで、コード ジェネレーターによって重複関数が作成されたかどうかを判別できます。このレポートでは、エントリポイント関数の下に重複関数のリストが表示されます。以下に例を示します。
複数の入力サイズに対して生成された重複関数
MATLAB コードが関数を複数回呼び出して、異なるサイズの入力を渡す場合、コード ジェネレーターが各サイズの関数の特殊化を作成することがあります。この問題を回避するには、coder.ignoreSize
を関数入力に使用します。たとえば、次のコードは coder.ignoreSize
を使用して、関数 indexOf
の複数のコピーが作成されることを回避します。
function [out1, out2] = test1(in) a = 1:10; b = 2:40; % Without coder.ignoreSize duplicate functions are generated out1 = indexOf(coder.ignoreSize(a), in); out2 = indexOf(coder.ignoreSize(b), in); end function index = indexOf(array, value) coder.inline('never'); for i = 1:numel(array) if array(i) == value index = i; return end end index = -1; end
コードを生成するには、次を入力します。
codegen test1 -config:lib -report -args {1}
さまざまな入力値用に生成された重複関数
MATLAB コードが関数を呼び出し、複数の異なる定数入力を渡す場合、コード ジェネレーターは異なる各定数に対して関数の特殊化を作成することができます。この場合、その値を不変の定数として処理しないようにコード ジェネレーターに指示するために coder.ignoreConst
を使用します。以下に例を示します。
function [out3, out4] = test2(in) c = ['a', 'b', 'c']; if in > 0 c(2)='d'; end out3 = indexOf(c, coder.ignoreConst('a')); out4 = indexOf(c, coder.ignoreConst('b')); end function index = indexOf(array, value) coder.inline('never'); for i = 1:numel(array) if array(i) == value index = i; return end end index = -1; end
コードを生成するには、次を入力します。
codegen test2 -config:lib -report -args {1}
さまざまな出力数に対して生成された重複関数
MATLAB コードが関数を呼び出して、さまざまな呼び出しサイトでさまざまな出力数を受け入れる場合、コード ジェネレーターは各呼び出しに対して特殊化を生成することができます。次に例を示します。
[a b] = foo(); c = foo();
各呼び出しで同じ数の出力を返すようにして、重複関数を回避するには、~
記号を使用します。
[a b] = foo(); [c, ~] = foo();
参考
coder.ignoreConst
| coder.varsize
| coder.ignoreSize