メインコンテンツ

Localizable ストレージ クラスをもつローカル変数の生成

信号の変数については、可能であれば、グローバル ストレージで生成するのではなく、関数に対してローカルとなるように生成します。ローカル変数を生成すると、それらの変数を生成コードから削除する最適化がコード ジェネレーターによって実装されません。ローカル変数を使用すると可観測性と可読性が高まり、生成コードをデバッグするときに便利です。

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

モデル例の確認

この例では、信号のローカル変数を生成する方法を示し、同じ信号に対してグローバル変数を生成する場合と比較します。

モデル LocalizableStorageClass を開きます。

open_system('LocalizableStorageClass')

モデル LocalizableStorageclass には、Localizable ストレージ クラスをもつ信号が 2 つ含まれています。Latching サブシステムでは、Latch というラベルの信号が Localizable ストレージ クラスになっています。Debug サブシステムでは、Debug というラベルの信号が Localizable ストレージ クラスになっています。

Localizable ストレージ クラスを使用したコードの生成

  1. 指定内容を確認するには、コード マッピング エディターを開きます。[C コード] タブで、[コード インターフェイス][個々の要素コードのマッピング] を選択します。

  2. [信号/状態] タブで [信号] を展開します。信号 [Latch][Debug] のストレージ クラスが [Localizable] に設定されています。

  3. コードを生成して表示します。Debug_b 関数には次のコードが含まれています。

    static void Debug_b(const real_T rtu_In1[6], const real_T rtu_In2[6], real_T
                        rtd_A[6])
    {
      real_T Debug;
      int32_T i;
      for (i = 0; i < 6; i++) {
        Debug = rtu_In1[i] * rtu_In2[i];
        rtd_A[i] += Debug;
      }
    }

    Latching 関数には次のコードが含まれています。

    static void Latching(const real_T rtu_In1[36], real_T rty_Out1[6], real_T
                         rty_Out2[6], real_T rtd_A[6])
    {
      real_T Latch[6];
      int32_T i;
      int32_T i_0;
      for (i = 0; i < 6; i++) {
        Latch[i] = rtd_A[i];
        rty_Out2[i] = -Latch[i];
      }
    
      for (i = 0; i < 6; i++) {
        rty_Out1[i] = 0.0;
        for (i_0 = 0; i_0 < 6; i_0++) {
          rty_Out1[i] += rtu_In1[6 * i_0 + i] * Latch[i_0];
        }
      }
    }

    どちらの関数にも、中間値を保持するための変数が含まれています。Debug_b 関数には変数 Debug が含まれています。Latching 関数には変数 Latch が含まれています。

Localizable ストレージ クラスを使用しないコードの生成

  1. 信号のストレージ クラスを Localizable から ExportToFile に変更します。コード マッピング エディターで、それぞれの信号のストレージ クラスを [ExportToFile] に設定します。

  2. コードを生成して表示します。LocalizableStorageClass.c ファイルには、次の 2 つのグローバル変数宣言が含まれています。

    real_T Debug[6];
    real_T Latch[6];

    Debug_b 関数には次のコードが含まれています。

    static void Debug_b(const real_T rtu_In1[6], const real_T rtu_In2[6], real_T
                        rtd_A[6])
    {
      int32_T i;
      for (i = 0; i < 6; i++) {
        Debug[i] = rtu_In1[i] * rtu_In2[i];
        rtd_A[i] += Debug[i];
      }
    }

    Latching 関数には次のコードが含まれています。

    static void Latching(const real_T rtu_In1[36], real_T rty_Out1[6], real_T
                         rty_Out2[6], real_T rtd_A[6])
    {
      int32_T i;
      int32_T i_0;
      for (i = 0; i < 6; i++) {
        Latch[i] = rtd_A[i];
        rty_Out2[i] = -Latch[i];
      }
    
      for (i = 0; i < 6; i++) {
        rty_Out1[i] = 0.0;
        for (i_0 = 0; i_0 < 6; i_0++) {
          rty_Out1[i] += rtu_In1[6 * i_0 + i] * Latch[i_0];
        }
      }
    }

    ラベル付き信号がグローバル変数であることを除き、コードの可読性と可観測性は Localizable ストレージ クラスが指定されている場合と同じです。

  3. Debug 信号と Latch 信号をコード マッピングから削除します。コード マッピング エディターで、それぞれの信号を選択して [信号の削除] ボタンをクリックします。

  4. モデルを保存します。

  5. コードを生成してレビューします。Debug_b 関数には次のコードが含まれています。

    static void Debug(const real_T rtu_In1[6], const real_T rtu_In2[6], real_T
                      rtd_A[6])
    {
      int32_T i;
      for (i = 0; i < 6; i++) {
        rtd_A[i] += rtu_In1[i] * rtu_In2[i];
      }
    }

    Latching 関数には次のコードが含まれています。

    static void Latching(const real_T rtu_In1[36], real_T rty_Out1[6], real_T
                         rty_Out2[6], real_T rtd_A[6])
    {
      int32_T i;
      int32_T i_0;
      for (i = 0; i < 6; i++) {
        rty_Out2[i] = -rtd_A[i];
        rty_Out1[i] = 0.0;
        for (i_0 = 0; i_0 < 6; i_0++) {
          rty_Out1[i] += rtu_In1[6 * i_0 + i] * rtd_A[i_0];
        }
      }
    }

    Localizable ストレージ クラスまたは ExportToFile ストレージ クラスがなく、コード ジェネレーターで Debug 変数と Latch 変数が削除されています。これらの変数がないと、生成コードの可読性と可観測性が低下します。

その他の情報

  • Localizable ストレージ クラスが指定された信号をコード ジェネレーターでローカルにするには、モデル コンフィギュレーション パラメーター [ローカルなブロックの出力を有効にする] を選択します。このパラメーターは既定でオンになっています。

  • 別々の再利用可能なサブシステムにある 2 つの信号に対して同じ Localizable ストレージ クラスを指定できます。したがって、Localizable ストレージ クラスが指定された再利用可能なサブシステムからライブラリ ブロックを作成することができます。

  • グローバルでなければならない信号に対しては、コード ジェネレーターはローカル変数を作成しません。コード ジェネレーターで信号をローカルにできない状況を次にいくつか示します。

    • 再利用できないサブシステムの入力信号と出力信号。[関数インターフェイス] パラメーターが Allow arguments (Optimized) に設定されている場合も同様です。

    • 受信側と駆動側のブロックで実行レートが異なるため信号で状態を保持している。

    • 条件付き実行サブシステムの境界を越える信号に Localizable が指定されている。

参考

トピック