生成コードでの暗黙的な拡張の最適化
生成コードでの暗黙的な拡張は既定で有効になっています。暗黙的な拡張を実行するためにコード ジェネレーターで生成コードに変更が加えられます。この生成コードの変更でオペランドを拡張するコードが追加される場合があります。オペランドの拡張は生成コードのパフォーマンスに影響することがあります。暗黙的な拡張を有効にしたコードの生成を参照してください。
暗黙的な拡張により、サポートされる演算子や関数からの出力のサイズが変わり、ワークフローでサイズおよび型の不一致エラーが発生することがあります。
生成コードで暗黙的な拡張を有効にする対象を詳細に制御するには、MATLAB® コードで次の関数を使用します。
たとえば、次のコードの抜粋について考えます。関数 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
を呼び出して、その関数の生成コードに対する暗黙的な拡張を無効にします。
たとえば、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
を使用します。
たとえば、次のコードの抜粋では、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
に与えられるオペランドのサイズは同じでなければなりません。
プロジェクトでの暗黙的な拡張の無効化
生成コードで暗黙的な拡張が必要ない場合や生成コードに影響する変更が望ましくない場合は、coder.config
オブジェクトの EnableImplicitExpansion
フラグを false
に設定して暗黙的な拡張をオフにします。このフラグは既定では true
に設定されています。
cfg = coder.config; cfg.EnableImplicitExpansion = false;
Simulink® モデルで暗黙的な拡張を無効にするには、モデル全体のパラメーター [MATLAB 関数の暗黙的な拡張を有効にする] を false
に設定します。あるいは、次のコマンドを使用します。
set_param(gcs,'EnableImplicitExpansion',false);
メモ
暗黙的な拡張をオフにする前に、外部コードで暗黙的な拡張が使用されていないことを確認してください。プロジェクト全体で暗黙的な拡張を無効にしてコードを生成すると、プロジェクトに外部ソースからの MATLAB コードが含まれている場合にエラーの原因になる可能性があります。
参考
coder.noImplicitExpansionInFunction
| coder.sameSizeBinaryOp