メインコンテンツ

グローバル変数の使用の最適化

R2026b

アプリケーションを調整して、実行速度とメモリ使用量のトレードオフを選択するには、生成されたコードに対してグローバル変数参照の最適化を選択します。

[コンフィギュレーション パラメーター] ダイアログ ボックスの [グローバル データ アクセスの最適化] ドロップダウン リストにある 3 つのパラメーター オプションがグローバル変数の使用の最適化を制御します。

  • [なし]。既定の最適化を使用します。この選択は、ほとんどのモデルでうまく機能します。コード ジェネレーターはローカル変数とグローバル変数の使用のバランスを調整します。RAM と ROM の消費量および実行速度のバランスを調整するコードを生成します。

  • グローバルを使用して一時的な結果を保持。グローバル変数を再利用することでコードの効率性と可読性が高まります。この最適化ではグローバル変数が再利用されるため、コード ジェネレーターによって定義される変数の数が削減されます。RAM と ROM の消費量、およびデータ コピーが削減されます。

  • グローバル データ アクセスの最小化。ローカル変数を使用してグローバル データをキャッシュすると、コード サイズが小さくなるため ROM の消費量が削減されます。コードがローカル変数参照に対して使用する命令数はグローバル変数参照に対して使用する命令数よりも少ないため、この最適化によって実行速度が改善されます。

    ローカル変数を使用してグローバル変数の使用を最小限に抑えることは、スタック使用量の制御にも関わってきます。たとえば、スタック サイズによって、コード ジェネレーターが生成コード内で割り当てることができるローカル変数とグローバル変数の数が決まります。詳細については、スタック領域の割り当てのカスタマイズを参照してください。

グローバルを使用して一時的な結果を保持

Use global to hold temporary results を選択する場合に対して、None を選択するとコード ジェネレーターはグローバル変数とローカル変数を使用します。

モデル例

モデル UseGlobalsForTemporaryResults では、Inport ブロックおよび Constant ブロックからの値が Assignment ブロックによって出力信号に代入されます。出力信号は Gain ブロックに接続されます。

Model with two inputs to an Assignment block, which feeds into a Gain block and then one output.

model = 'UseGlobalsForTemporaryResults';
load_system('UseGlobalsForTemporaryResults')

最適化を使用しないコードの生成

  1. [コンフィギュレーション パラメーター] ダイアログ ボックスで、[信号ストレージの再利用] パラメーターが選択されていることを確認します。

  2. [コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して None を選択するか、MATLAB® コマンド ウィンドウで次のコマンドを入力します。

set_param('UseGlobalsForTemporaryResults','GlobalVariableUsage','None');

モデルをビルドします。

slbuild(model);
### Searching for referenced models in model 'UseGlobalsForTemporaryResults'.
### Total of 1 models to build.
### Starting top model code generation target build for: UseGlobalsForTemporaryResults
### Successful completion of build procedure for: UseGlobalsForTemporaryResults

Build Summary

Top model targets:

Model                          Build Reason                                             Status                        Build Duration
====================================================================================================================================
UseGlobalsForTemporaryResults  Target (UseGlobalsForTemporaryResults.c) did not exist.  Code generated and compiled.  0h 0m 8.067s

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 8.4484s

最適化を行わない生成コードを表示します。ここで UseGlobalsForTemporaryResults.c の一部を示します。

cfile = fullfile(pwd,'UseGlobalsForTemporaryResults_ert_rtw',...
    'UseGlobalsForTemporaryResults.c');
coder.example.extractLines(cfile,'/* Model step','/* Model initialize',1, 0);
/* Model step function */
void UseGlobalsForTemporaryResults_step(void)
{
  real_T rtb_Assignment[5];
  int32_T i;

  /* SignalConversion generated from: '<Root>/Assignment' incorporates:
   *  Constant: '<Root>/Constant'
   */
  for (i = 0; i < 5; i++) {
    rtb_Assignment[i] = rtCP_Constant_Value[i];
  }

  /* End of SignalConversion generated from: '<Root>/Assignment' */

  /* Assignment: '<Root>/Assignment' incorporates:
   *  Inport: '<Root>/In1'
   */
  rtb_Assignment[1] = rtU.In1;

  /* Outport: '<Root>/Out1' incorporates:
   *  Gain: '<Root>/Gain'
   */
  for (i = 0; i < 5; i++) {
    rtY.Out1[i] = 2.0 * rtb_Assignment[i];
  }

  /* End of Outport: '<Root>/Out1' */
}

このコードは値をローカル ベクトル rtb_Assignment に代入します。最後のステートメントでは、ローカル ベクトル rtb_Assignment の値をグローバル ベクトル rtY.Out1 にコピーします。グローバル変数の参照が少ないほど実行速度が速くなります。このコードでは、ローカル変数参照よりもグローバル変数参照に多くの命令を使用します。

静的コード メトリクス レポートで、グローバル変数セクションを確認します。

  1. コード生成レポート ウィンドウで、[静的コード メトリクス レポート] を選択します。

  2. Global Variables セクションまで下にスクロールします。

  3. 各変数の前にある [+] 記号を選択して展開します。

Table of global variables with rows expanded to show the size, number of reads and writes, and number of reads and writes in a function for each variable.

グローバル変数に対する読み取りと書き込みの合計回数は 2 回です。

最適化を使用したコードの生成

[コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して Use global to hold temporary results を選択するか、MATLAB コマンド ウィンドウで次のコマンドを入力します。

set_param('UseGlobalsForTemporaryResults',...
    'GlobalVariableUsage','Use global to hold temporary results');

モデルをビルドします。

slbuild(model);
### Searching for referenced models in model 'UseGlobalsForTemporaryResults'.
### Total of 1 models to build.
### Starting top model code generation target build for: UseGlobalsForTemporaryResults
### Successful completion of build procedure for: UseGlobalsForTemporaryResults

Build Summary

Top model targets:

Model                          Build Reason                                                         Status                        Build Duration
================================================================================================================================================
UseGlobalsForTemporaryResults  Model or library UseGlobalsForTemporaryResults has unsaved changes.  Code generated and compiled.  0h 0m 6.1858s

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 6.6848s

最適化を行った生成コードを表示します。ここで UseGlobalsForTemporaryResults.c の一部を示します。

cfile = fullfile(pwd,'UseGlobalsForTemporaryResults_ert_rtw',...
    'UseGlobalsForTemporaryResults.c');
coder.example.extractLines(cfile,'/* Model step','/* Model initialize',1, 0);
/* Model step function */
void UseGlobalsForTemporaryResults_step(void)
{
  int32_T i;

  /* SignalConversion generated from: '<Root>/Assignment' incorporates:
   *  Assignment: '<Root>/Assignment'
   *  Constant: '<Root>/Constant'
   */
  for (i = 0; i < 5; i++) {
    rtY.Out1[i] = rtCP_Constant_Value[i];
  }

  /* End of SignalConversion generated from: '<Root>/Assignment' */

  /* Assignment: '<Root>/Assignment' incorporates:
   *  Inport: '<Root>/In1'
   */
  rtY.Out1[1] = rtU.In1;

  /* Outport: '<Root>/Out1' incorporates:
   *  Assignment: '<Root>/Assignment'
   *  Gain: '<Root>/Gain'
   */
  for (i = 0; i < 5; i++) {
    rtY.Out1[i] *= 2.0;
  }

  /* End of Outport: '<Root>/Out1' */
}

このコードは、ローカル変数を使用せずに値をグローバル ベクトル rtY.Out1 に代入します。この代入によって ROM と RAM の消費量が改善され、データ コピーが削減されます。このコードは、最後に値をコピーする代わりに、各代入の代入先変数に値を配置します。静的コード メトリクス レポートで、グローバル変数セクションを確認します。

Table of global variables with rows expanded to show the size, number of reads and writes, and number of reads and writes in a function for each variable.

グローバル変数を使用してローカル結果を保持した結果、グローバル変数の読み取りおよび書き込みの合計回数が 2 回から 5 回に増加しました。この最適化によってグローバル変数が再利用されるため、データ コピーが削減されます。

コード生成レポートを閉じます。

グローバル データ アクセスの最小化

グローバル変数に対する読み取りおよび書き込みを低い頻度で実行する最適化されたコードを生成します。

モデル例

モデル MinimizeGlobalDataAccess では、5 個の信号が Multiport Switch ブロックに入力されます。

model = 'MinimizeGlobalDataAccess';
load_system('MinimizeGlobalDataAccess.slx')

MinimizeGlobalDataAccessModel.png

最適化を使用しないコードの生成

  1. [コンフィギュレーション パラメーター] ダイアログ ボックスで、[信号ストレージの再利用] パラメーターが選択されていることを確認します。

  2. [コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して None を選択するか、MATLAB® コマンド ウィンドウで次のコマンドを入力します。

set_param('MinimizeGlobalDataAccess','GlobalVariableUsage','None');

モデルをビルドします。

slbuild(model);
### Searching for referenced models in model 'MinimizeGlobalDataAccess'.
### Total of 1 models to build.
### Starting top model code generation target build for: MinimizeGlobalDataAccess
### Successful completion of build procedure for: MinimizeGlobalDataAccess

Build Summary

Top model targets:

Model                     Build Reason                                        Status                        Build Duration
==========================================================================================================================
MinimizeGlobalDataAccess  Target (MinimizeGlobalDataAccess.c) did not exist.  Code generated and compiled.  0h 0m 7.8714s

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 8.3667s

最適化を行わない生成コードを表示します。ここで MinimizeGlobalDataAccess.c の一部を示します。

cfile = fullfile(pwd,'MinimizeGlobalDataAccess_ert_rtw',...
    'MinimizeGlobalDataAccess.c');
coder.example.extractLines(cfile,'/* Model step','/* Model initialize',1, 0);
/* Model step function */
void MinimizeGlobalDataAccess_step(void)
{
  /* MultiPortSwitch: '<Root>/Multiport Switch' incorporates:
   *  Inport: '<Root>/In1'
   */
  switch ((int32_T)rtU.In1) {
   case 1:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant'
     */
    rtY.Out1 = 1.0;
    break;

   case 2:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant1'
     */
    rtY.Out1 = 2.0;
    break;

   case 3:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant2'
     */
    rtY.Out1 = 3.0;
    break;

   default:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant3'
     */
    rtY.Out1 = 4.0;
    break;
  }

  /* End of MultiPortSwitch: '<Root>/Multiport Switch' */
}

静的コード メトリクス レポートで、Global Variables セクションを調べます。

  1. コード生成レポート ウィンドウで、[静的コード メトリクス レポート] を選択します。

  2. Global Variables セクションまで下にスクロールします。

  3. 各変数の前にある [+] 記号を選択して展開します。

グローバル変数に対する読み取りと書き込みの合計回数は 5 回です。

最適化の有効化とコードの生成

[コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して Minimize global data access を選択するか、MATLAB コマンド ウィンドウで次のコマンドを入力します。

set_param('MinimizeGlobalDataAccess',...
    'GlobalVariableUsage','Minimize global data access');

モデルをビルドします。

slbuild(model);
### Searching for referenced models in model 'MinimizeGlobalDataAccess'.
### Total of 1 models to build.
### Starting top model code generation target build for: MinimizeGlobalDataAccess
### Successful completion of build procedure for: MinimizeGlobalDataAccess

Build Summary

Top model targets:

Model                     Build Reason                                                    Status                        Build Duration
======================================================================================================================================
MinimizeGlobalDataAccess  Model or library MinimizeGlobalDataAccess has unsaved changes.  Code generated and compiled.  0h 0m 6.7277s

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 7.1791s

最適化を行った生成コードを表示します。ここで MinimizeGlobalDataAccess.c の一部を示します。

cfile = fullfile(pwd,'MinimizeGlobalDataAccess_ert_rtw',...
    'MinimizeGlobalDataAccess.c');
coder.example.extractLines(cfile,'/* Model step','/* Model initialize',1, 0);
/* Model step function */
void MinimizeGlobalDataAccess_step(void)
{
  real_T tmp_Out1;

  /* MultiPortSwitch: '<Root>/Multiport Switch' incorporates:
   *  Inport: '<Root>/In1'
   */
  switch ((int32_T)rtU.In1) {
   case 1:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant'
     */
    tmp_Out1 = 1.0;
    break;

   case 2:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant1'
     */
    tmp_Out1 = 2.0;
    break;

   case 3:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant2'
     */
    tmp_Out1 = 3.0;
    break;

   default:
    /* Outport: '<Root>/Out1' incorporates:
     *  Constant: '<Root>/Constant3'
     */
    tmp_Out1 = 4.0;
    break;
  }

  /* End of MultiPortSwitch: '<Root>/Multiport Switch' */

  /* Outport: '<Root>/Out1' */
  rtY.Out1 = tmp_Out1;
}

MinimizeGlobalDataAccess.c のコードは、定数値を各 case ステートメントのローカル変数 tmp_Out1 に代入します。コード内の最後のステートメントでは、tmp_Out1 の値をグローバル変数 rtY.Out1 にコピーします。グローバル変数の参照が少ないほど命令の数が減り、実行速度が速くなります。

静的コード メトリクス レポートで、Global Variables セクションを調べます。グローバル データ アクセスを最小限に抑えた結果、グローバル変数に対する読み取りと書き込みの合計回数が 5 回から 2 回に削減されました。

コード生成レポートを閉じます。

参考

| |

トピック