データ コピーからポインターの割り当てへの変換
コード ジェネレーターは、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);
### Searching for referenced models in model 'rtwdemo_pointer_conversion'. ### Total of 1 models to build. ### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets: Model Build Reason Status Build Duration ============================================================================================================================= rtwdemo_pointer_conversion Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 14.703s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 15.208s
最適化を行わない生成コードを表示します。ここで 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);
### Searching for referenced models in model 'rtwdemo_pointer_conversion'. ### Total of 1 models to build. ### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets: Model Build Reason Status Build Duration ========================================================================================================= rtwdemo_pointer_conversion Generated code was out of date. Code generated and compiled. 0h 0m 12.215s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 12.848s
最適化を行った生成コードを表示します。ここで 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 しきい値 (バイト)