Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

データ コピーからポインターの割り当てへの変換

コード ジェネレーターは、for ループ制御による要素割り当てと関数 memcpy の呼び出しをポインターの割り当てで置換することで、ベクトル信号割り当ての生成コードを最適化します。ポインターの代入は計算コストの高いデータ コピーを回避します。そのため、for ループ制御による要素割り当てと関数 memcpy の呼び出しよりも、使用するスタック領域が削減され、実行速度が速くなります。大規模なデータセットをベクトル信号に割り当てる場合、この最適化によってコード効率が大幅に向上します。

ベクトル信号割り当ての生成コードを最適化するためのモデル設定

この最適化を適用するには、次のようにします。

  1. ターゲットが関数 memcpy をサポートすることを確認します。

  2. モデルで大量のデータを移動させるために、ベクトル信号割り当て (Y=expression など) を使用するかどうかを決定します。たとえば、モデルで Selector ブロックを使用して、ベクトル、行列、または多次元信号から入力要素を選択できます。

  3. [最適化] ペインでは、既定でオンになっている [ベクトルの割り当てに対して memcpy を使用] パラメーターによって関連する [memcpy しきい値 (バイト)] パラメーターが有効化されます。

  4. [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)

参考

|

関連するトピック