生成コードでの暗黙的な拡張の最適化
生成コードでの暗黙的な拡張は既定で有効になっています。暗黙的な拡張を実行するためにコード ジェネレーターで生成コードに変更が加えられます。この生成コードの変更でオペランドを拡張するコードが追加される場合があります。オペランドの拡張は生成コードのパフォーマンスに影響することがあります。暗黙的な拡張を有効にしたコードの生成 (MATLAB Coder)を参照してください。
暗黙的な拡張により、サポートされる演算子や関数からの出力のサイズが変わり、ワークフローでサイズおよび型の不一致エラーが発生することがあります。
生成コードで暗黙的な拡張を有効にする対象を詳細に制御するには、MATLAB® コードで次の関数を使用します。
coder.noImplicitExpansionInFunction(MATLAB Coder)coder.sameSizeBinaryOp(MATLAB Coder)
たとえば、次のコードの抜粋について考えます。関数 vector_sum はサイズに互換性がある 2 つの配列の和を求めます。
function out = vector_sum(a,b) out = b + a; end
オペランド a および b の型の定義は次のとおりです。
a_type = coder.typeof(1,[2 1]) %size: 2x1 b_type = coder.typeof(1,[2 Inf]) %size: 2x:inf
暗黙的な拡張がない場合、変数 out のサイズは 2x1 として計算されます。

暗黙的な拡張がある場合、変数 out のサイズは 2x:? として計算されます。

次のコードの抜粋は、関数 vector_sum の生成コードについて、暗黙的な拡張を無効にした場合と有効にした場合でどのように変わるかを示したものです。このコードを生成するには、オペランド a および b の型を次のように定義します。
a_type = coder.typeof(1,[1 Inf]) %size: 1x:inf b_type = coder.typeof(1,[1 Inf]) %size: 1x:inf
| 暗黙的な拡張を無効にした生成コード | 暗黙的な拡張を有効にした生成コード |
|---|---|
void vector_sum(const emxArray_real_T *a, const emxArray_real_T *b,
emxArray_real_T *out)
{
int i;
int loop_ub;
i = out->size[0] * out->size[1];
out->size[0] = 1;
out->size[1] = b->size[1];
emxEnsureCapacity_real_T(out, i);
loop_ub = b->size[1];
for (i = 0; i < loop_ub; i++) {
out->data[i] = b->data[i] + a->data[i];
}
}
| static void plus(emxArray_real_T *out, const emxArray_real_T *b,
const emxArray_real_T *a)
{
int i;
....
if (a->size[1] == 1) {
out->size[1] = b->size[1];
} else {
out->size[1] = a->size[1];
}
....
if (a->size[1] == 1) {
loop_ub = b->size[1];
} else {
loop_ub = a->size[1];
}
for (i = 0; i < loop_ub; i++) {
out->data[i] = b->data[i * stride_0_1] + a->data[i * stride_1_1];
}
}
void vector_sum(const emxArray_real_T *a, const emxArray_real_T *b,
emxArray_real_T *out)
{
int i;
int loop_ub;
if (b->size[1] == a->size[1]) {
i = out->size[0] * out->size[1];
out->size[0] = 1;
out->size[1] = b->size[1];
emxEnsureCapacity_real_T(out, i);
loop_ub = b->size[1];
for (i = 0; i < loop_ub; i++) {
out->data[i] = b->data[i] + a->data[i];
}
} else {
plus(out, b, a);
}
} |
coder.noImplicitExpansionInFunction を使用した指定した関数での暗黙的な拡張の無効化
暗黙的な拡張がプロジェクトでは必要で、特定の関数で必要ない場合、該当する関数内で coder.noImplicitExpansionInFunction (MATLAB Coder) を呼び出して、その関数の生成コードに対する暗黙的な拡張を無効にします。
たとえば、vector_sum に対して生成される次のコードでは暗黙的な拡張が適用されません。
| MATLAB コード | coder.sameSizeBinaryOp を使用した生成コード |
|---|---|
function out = vector_sum(a,b) coder.noImplicitExpansionInFunction(); out = a + b; end a = coder.typeof(1,[1 Inf]) %size: 1x:inf b = coder.typeof(1,[1 Inf]) %size: 1x:inf codegen vector_sum -launchreport ... -args {a,b} -config:lib | void vector_sum(const emxArray_real_T *a,
const emxArray_real_T *b, emxArray_real_T *out)
{
int i;
int loop_ub;
i = out->size[0] * out->size[1];
out->size[0] = 1;
out->size[1] = a->size[1];
emxEnsureCapacity_real_T(out, i);
loop_ub = a->size[1];
for (i = 0; i < loop_ub; i++) {
out->data[i] = a->data[i] + b->data[i];
}
} |
メモ
coder.noImplicitExpansionInFunction の場合、MATLAB コードでは暗黙的な拡張は無効になりません。生成コードでのみ暗黙的な拡張が無効になります。
coder.sameSizeBinaryOp を使用した特定の二項演算に対する暗黙的な拡張の無効化
エラー チェックを実行してオペランドが同じサイズであることを確認し、コード ジェネレーターでその関数に対して暗黙的に拡張されるコードが生成されないようにするには、関数 coder.sameSizeBinaryOp (MATLAB Coder) を使用します。
たとえば、次のコードの抜粋では、coder.sameSizeBinaryOp を使用して暗黙的な拡張なしで加算演算を適用しています。
| MATLAB コード | 生成コード |
|---|---|
function out = vector_sum(a,b) out = coder.sameSizeBinaryOp(@plus, a, b); end a = coder.typeof(1,[1 Inf]) %size: 1x:inf b = coder.typeof(1,[1 Inf]) %size: 1x:inf codegen vector_sum -launchreport ... -args {a,b} -config:lib | void vector_sum(const emxArray_real_T *a,
const emxArray_real_T *b, emxArray_real_T *out)
{
int i;
int loop_ub;
i = out->size[0] * out->size[1];
out->size[0] = 1;
out->size[1] = a->size[1];
emxEnsureCapacity_real_T(out, i);
loop_ub = a->size[1];
for (i = 0; i < loop_ub; i++) {
out->data[i] = a->data[i] + b->data[i];
}
} |
coder.sameSizeBinaryOp ではスカラー拡張はサポートされません。coder.sameSizeBinaryOp に与えられるオペランドのサイズは同じでなければなりません。
プロジェクトでの暗黙的な拡張の無効化
暗黙的な拡張は既定で有効になっています。生成コードで暗黙的な拡張が必要ない場合は、[暗黙的な拡張を有効にする] (MATLAB Coder) コンフィギュレーション パラメーターを無効にできます。あるいは、コード構成オブジェクトの EnableImplicitExpansion プロパティを false に設定できます。
Simulink® モデルで暗黙的な拡張を無効にするには、モデル全体のパラメーター [MATLAB 関数の暗黙的な拡張を有効にする] を false に設定します。あるいは、次のコマンドを使用します。
set_param(gcs,'EnableImplicitExpansion',false);メモ
暗黙的な拡張をオフにする前に、外部コードで暗黙的な拡張が使用されていないことを確認してください。プロジェクト全体で暗黙的な拡張を無効にしてコードを生成すると、プロジェクトに外部ソースからの MATLAB コードが含まれている場合にエラーの原因になる可能性があります。
参考
coder.noImplicitExpansionInFunction (MATLAB Coder) | coder.sameSizeBinaryOp (MATLAB Coder)
トピック
- 暗黙的な拡張を有効にしたコードの生成 (MATLAB Coder)
- 基本的な演算で互換性のある配列サイズ
- エラーの解決: 左辺は固定サイズだが右辺は可変サイズ (MATLAB Coder)