グローバル変数の使用の最適化
アプリケーションを調整して、実行速度とメモリ使用量のトレードオフを選択するには、生成されたコードに対してグローバル変数参照の最適化を選択します。
[コンフィギュレーション パラメーター] ダイアログ ボックスの [グローバル データ アクセスの最適化] ドロップダウン リストにある 3 つのパラメーター オプションがグローバル変数の使用の最適化を制御します。
なし
。既定の最適化を使用します。この選択は、ほとんどのモデルでうまく機能します。コード ジェネレーターはローカル変数とグローバル変数の使用のバランスを調整します。RAM と ROM の消費量および実行速度のバランスを調整するコードを生成します。グローバルを使用して一時的な結果を保持
。グローバル変数を再利用することでコードの効率性と可読性が高まります。この最適化ではグローバル変数が再利用されるため、コード ジェネレーターによって定義される変数の数が削減されます。RAM と ROM の消費量、およびデータ コピーが削減されます。グローバル データ アクセスの最小化
。ローカル変数を使用してグローバル データをキャッシュすると、コード サイズが小さくなるため ROM の消費量が削減されます。コードがローカル変数参照に対して使用する命令数はグローバル変数参照に対して使用する命令数よりも少ないため、この最適化によって実行速度が改善されます。ローカル変数を使用してグローバル変数の使用を最小限に抑えることは、スタック使用量の制御にも関わってきます。たとえば、スタック サイズによって、コード ジェネレーターが生成コード内で割り当てることができるローカル変数とグローバル変数の数が決まります。詳細については、スタック領域の割り当てのカスタマイズを参照してください。
グローバルを使用して一時的な結果を保持
Use global to hold temporary
results
を選択する場合に対して、None
を選択するとコード ジェネレーターはグローバル変数とローカル変数を使用します。
モデル例
モデル UseGlobalsForTemporaryResults
では、Inport ブロックおよび Constant ブロックからの値が Assignment ブロックによって出力信号に代入されます。出力信号は Gain ブロックに接続されます。
model = 'UseGlobalsForTemporaryResults'; load_system('UseGlobalsForTemporaryResults')
最適化を使用しないコードの生成
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[信号ストレージの再利用] パラメーターが選択されていることを確認します。
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して
None
を選択するか、MATLAB® コマンド ウィンドウで次のコマンドを入力します。
set_param('UseGlobalsForTemporaryResults','GlobalVariableUsage','None');
モデルを作成します。
slbuild(model);
### Starting build procedure for: UseGlobalsForTemporaryResults ### Successful completion of build procedure for: UseGlobalsForTemporaryResults Build Summary Top model targets built: Model Action Rebuild Reason =============================================================================================================== UseGlobalsForTemporaryResults 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 14.501s
最適化を行わない生成コードを表示します。ここで 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
にコピーします。グローバル変数の参照が少ないほど実行速度が速くなります。このコードでは、ローカル変数参照よりもグローバル変数参照に多くの命令を使用します。
静的コード メトリクス レポートで、グローバル変数セクションを確認します。
コード生成レポート ウィンドウで、[静的コード メトリクス レポート] を選択します。
Global Variables
セクションまで下にスクロールします。各変数の前にある [+] 記号を選択して展開します。
グローバル変数に対する読み取りと書き込みの合計回数は 2 回です。
最適化を使用したコードの生成
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して Use global to hold temporary results
を選択するか、MATLAB コマンド ウィンドウで次のコマンドを入力します。
set_param('UseGlobalsForTemporaryResults',... 'GlobalVariableUsage','Use global to hold temporary results');
モデルを作成します。
slbuild(model);
### Starting build procedure for: UseGlobalsForTemporaryResults ### Successful completion of build procedure for: UseGlobalsForTemporaryResults Build Summary Top model targets built: Model Action Rebuild Reason ============================================================================================== UseGlobalsForTemporaryResults 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 13.228s
最適化を行った生成コードを表示します。ここで 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 の消費量が改善され、データ コピーが削減されます。このコードは、最後に値をコピーする代わりに、各代入の代入先変数に値を配置します。静的コード メトリクス レポートで、グローバル変数セクションを確認します。
グローバル変数を使用してローカル結果を保持した結果、グローバル変数の読み取りおよび書き込みの合計回数が 2 回から 5 回に増加しました。この最適化によってグローバル変数が再利用されるため、データ コピーが削減されます。
コード生成レポートを閉じます。
グローバル データ アクセスの最小化
グローバル変数に対する読み取りおよび書き込みを低い頻度で実行する最適化されたコードを生成します。
モデル例
モデル MinimizeGlobalDataAccess
では、5 個の信号が Multiport Switch ブロックに入力されます。
model = 'MinimizeGlobalDataAccess'; load_system('MinimizeGlobalDataAccess.slx')
最適化を使用しないコードの生成
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[信号ストレージの再利用] パラメーターが選択されていることを確認します。
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して
None
を選択するか、MATLAB® コマンド ウィンドウで次のコマンドを入力します。
set_param('MinimizeGlobalDataAccess','GlobalVariableUsage','None');
モデルを作成します。
slbuild(model);
### Starting build procedure for: MinimizeGlobalDataAccess ### Successful completion of build procedure for: MinimizeGlobalDataAccess Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================================== MinimizeGlobalDataAccess 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 12.267s
最適化を行わない生成コードを表示します。ここで 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
セクションを調べます。
コード生成レポート ウィンドウで、[静的コード メトリクス レポート] を選択します。
Global Variables
セクションまで下にスクロールします。各変数の前にある [+] 記号を選択して展開します。
グローバル変数に対する読み取りと書き込みの合計回数は 5 回です。
最適化の有効化とコードの生成
[コンフィギュレーション パラメーター] ダイアログ ボックスで、[グローバル データ アクセスの最適化] パラメーターに対して Minimize global data access
を選択するか、MATLAB コマンド ウィンドウで次のコマンドを入力します。
set_param('MinimizeGlobalDataAccess',... 'GlobalVariableUsage','Minimize global data access');
モデルを作成します。
slbuild(model);
### Starting build procedure for: MinimizeGlobalDataAccess ### Successful completion of build procedure for: MinimizeGlobalDataAccess Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================= MinimizeGlobalDataAccess 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 11.708s
最適化を行った生成コードを表示します。ここで 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 回に削減されました。
コード生成レポートを閉じます。