このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
データ コピーからポインターの割り当てへの変換
コード ジェネレーターは、for
ループ制御による要素割り当てと関数 memcpy
の呼び出しをポインターの割り当てで置換することで、ベクトル信号割り当ての生成コードを最適化します。ポインターの代入は計算コストの高いデータ コピーを回避します。そのため、for
ループ制御による要素割り当てと関数 memcpy
の呼び出しよりも、使用するスタック領域が削減され、実行速度が速くなります。大規模なデータセットをベクトル信号に割り当てる場合、この最適化によってコード効率が大幅に向上します。
ベクトル信号割り当ての生成コードを最適化するためのモデル設定
この最適化を適用するには、次のようにします。
ターゲットが関数
memcpy
をサポートすることを確認します。モデルで大量のデータを移動させるために、ベクトル信号割り当て (
Y=expression
など) を使用するかどうかを決定します。たとえば、モデルで Selector ブロックを使用して、ベクトル、行列、または多次元信号から入力要素を選択できます。[最適化] ペインでは、既定でオンになっている [ベクトルの割り当てに対して memcpy を使用] パラメーターによって関連する [memcpy しきい値 (バイト)] パラメーターが有効化されます。
[memcpy しきい値 (バイト)] の設定を検証します。既定では、関数
memcpy
の呼び出しまたはポインターの割り当てが生成コード内のfor
ループを置換できる最小配列サイズとして 64 バイトが指定されます。アプリケーションのベクトル信号の割り当てで使用される配列サイズ、およびしきい値選択に関するターゲット環境の考慮事項に基づいて、既定の値をそのまま使用するか、別の配列サイズを指定します。
モデル例
モデル例 rtwdemo_pointer_conversion
を開きます。このモデルは Switch ブロックを使用してデータをベクトル信号に割り当てます。その後、この信号は Bus Selector ブロックに接続されます。
model='rtwdemo_pointer_conversion';
open_system(model);
最適化を使用しないコードの生成
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[ベクトルの割り当てに対して memcpy を使用] パラメーターをオフにします。あるいは、以下のコマンド ラインを使用します。
set_param(model, 'EnableMemcpy','off');
Ctrl+B を押してコードを生成します。あるいは、以下のコマンド ラインを使用します。
slbuild(model);
### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets built: Model Action Rebuild Reason ============================================================================================================ rtwdemo_pointer_conversion Code generated and compiled. Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 20.145s
最適化を行わない生成コードを表示します。ここで rtwdemo_pointer_conversion.c
の一部を示します。
cfile = fullfile('rtwdemo_pointer_conversion_ert_rtw','rtwdemo_pointer_conversion.c'); coder.example.extractLines(cfile,'/* Model step','/* Model initialize',1, 0);
/* Model step function */ void rtwdemo_pointer_conversion_step(void) { int32_T i; int16_T rtb_dataX[100]; int16_T rtb_dataY[100]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant' * Constant: '<Root>/Constant1' * Constant: '<Root>/Constant2' * Constant: '<Root>/Constant3' * Inport: '<Root>/In1' */ for (i = 0; i < 100; i++) { if (rtU.In1) { rtb_dataX[i] = rtCP_Constant_Value[i]; rtb_dataY[i] = rtCP_Constant1_Value[i]; } else { rtb_dataX[i] = rtCP_Constant2_Value[i]; rtb_dataY[i] = rtCP_Constant3_Value[i]; } } /* End of Switch generated from: '<Root>/Switch' */ /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates: * Inport: '<Root>/In2' * Outport: '<Root>/Out1' */ /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic' * Input0 Data Type: Integer S16 * Input1 Data Type: Integer S16 * Input2 Data Type: Integer S16 * Output0 Data Type: Integer S16 * Lookup Method: Linear_Endpoint * */ LookUp_S16_S16( &(rtY.Out1), &rtb_dataY[0], rtU.In2, &rtb_dataX[0], 99U); }
最適化を行わない場合、生成コードには for
ループ制御による要素割り当てが含まれます。
最適化の有効化とコードの生成
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[ベクトルの割り当てに対して memcpy を使用] パラメーターをオンにします。
set_param(model, 'EnableMemcpy','on')
コードを生成します。
slbuild(model);
### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets built: Model Action Rebuild Reason =========================================================================================== rtwdemo_pointer_conversion Code generated and compiled. Generated code was out of date. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 16.71s
最適化を行わない生成コードを表示します。ここで rtwdemo_pointer_conversion.c
の一部を示します。
cfile = fullfile('rtwdemo_pointer_conversion_ert_rtw','rtwdemo_pointer_conversion.c'); coder.example.extractLines(cfile,'/* Model step','/* Model initialize',1, 0);
/* Model step function */ void rtwdemo_pointer_conversion_step(void) { const int16_T *rtb_dataX_0; const int16_T *rtb_dataY_0; /* Inport: '<Root>/In1' */ if (rtU.In1) { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant' */ rtb_dataX_0 = &rtCP_Constant_Value[0]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant1' */ rtb_dataY_0 = &rtCP_Constant1_Value[0]; } else { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant2' */ rtb_dataX_0 = &rtCP_Constant2_Value[0]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant3' */ rtb_dataY_0 = &rtCP_Constant3_Value[0]; } /* End of Inport: '<Root>/In1' */ /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates: * Inport: '<Root>/In2' * Outport: '<Root>/Out1' */ /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic' * Input0 Data Type: Integer S16 * Input1 Data Type: Integer S16 * Input2 Data Type: Integer S16 * Output0 Data Type: Integer S16 * Lookup Method: Linear_Endpoint * */ LookUp_S16_S16( &(rtY.Out1), &rtb_dataY_0[0], rtU.In2, &rtb_dataX_0[0], 99U); }
[memcpy しきい値 (バイト)] パラメーターの設定は生成コード内の配列サイズを下回っているため、最適化されたコードにはベクトル信号割り当てのためのポインターの割り当てが含まれています。
bdclose(model)
参考
ベクトルの割り当てに対して memcpy を使用 | memcpy しきい値 (バイト)