Main Content

固定小数点ユーティリティ関数の生成の制御

指定された最小値および最大値を使用した生成コードの最適化

Fixed-Point Designer™ ソフトウェアでは、表現可能な最小値と最大値および定数値を使用して、生成コードを最適化できるかどうかを判断します。最適化とは、たとえば生成コードから不要なユーティリティ関数や飽和コードを排除することです。

この最適化により、以下のことを実現できます。

  • ROM と RAM の消費量の低減

  • 実行速度の向上

[指定した最小値と最大値を使用した最適化] コンフィギュレーション パラメーターを選択すると、"設計の最小値と最大値" とも呼ばれる入力範囲情報が考慮されます。この情報はモデルの信号とパラメーターに対してユーザーが指定します。これらの最小値と最大値を使用してモデルのダウンストリーム信号の範囲情報が得られ、可能であれば常にこの範囲情報を使用して、生成コード内の数学演算が簡略化されます。

必要条件

[指定した最小値と最大値を使用した最適化] パラメーターは、ERT ベースのターゲットのみに表示され、コード生成時には Embedded Coder® ライセンスを必要とします。

モデルの設定方法

最適化の実現性を高めるには、以下のようにします。

  • 設計の最小値と最大値の情報をできるだけ多く提供します。以下の項目についてモデルの信号とパラメーターの最小値と最大値を指定します。

    • Inport ブロックと Outport ブロック

    • ブロック出力

    • ブロック入力 (MATLAB Function ブロックや Stateflow® Chart ブロックなど)

    • Simulink.Signal オブジェクト

  • コードを生成する前に、信号とパラメーターの最小値と最大値をテストします。そうしないと、最適化の際に数値がシミュレーションと合わなくなる可能性があります。シミュレーション範囲のチェックを有効にした状態で、モデルをシミュレーションできます。エラーまたは警告が発生したら、問題を解決してからコードを生成してください。

     シミュレーション範囲チェック機能を有効にする方法

  • 2 進小数点専用 (2 のべき乗) スケーリングで固定小数点データ型を使用します。

  • 設計の最小値と最大値情報をブロックの上流のブロック入力にできるだけ近い位置で指定します。ブロック出力の最小値と最大値を指定すると、これらの値がすぐ下流のブロック出力に影響を及ぼす可能性が高くなります。詳細は、指定された最小値と最大値を使用した不要なユーティリティ関数の排除を参照してください。

最適化を有効にする方法

  1. [コンフィギュレーション パラメーター] ダイアログ ボックスの [コード生成][システム ターゲット ファイル] で、Embedded Real-Time (ERT) ターゲットを選択するように設定します (Embedded Coder ライセンスが必要)。

  2. モデルの設定方法で説明しているヒントに従ってモデルの信号とパラメーターの設計の最小値と最大値を指定します。

  3. [最適化][詳細設定パラメーター][指定した最小値と最大値を使用した最適化] コンフィギュレーション パラメーターを選択します。

制限

  • この最適化は以下の場合には実施されません。

    • マルチワード処理

    • 勾配とバイアス スケーリングが指定されている固定小数点データ型

    • 小数部の長さがゼロでない加算

  • この最適化では以下の場合に最小値と最大値が考慮されません。

    • Merge ブロック入力。この問題を回避するには、Merge ブロック出力で Simulink.Signal オブジェクトを使用してこのオブジェクトの範囲を指定します。

    • バス要素

    • Outport ブロックに直接接続される条件付き実行サブシステム (Triggered Subsystem など) のブロック出力。

      条件付き実行サブシステムの Outport ブロックは、システムがトリガーされない場合のみの使用に指定された初期値をもつことができます。ただしこの場合は、範囲がブロックの初期値を含まない可能性があるので、最適化でブロック出力の範囲は使用できません。

  • 精度について制限事項がありますが、これは最小値と最大値が倍精度として指定されているからです。最小値または最大値の真の値を倍精度として表現できない場合、真の設計範囲をカバーするように最小値と最大値を正しく丸めていることを確認してください。

  • モデルに再利用可能なサブシステムの複数のインスタンスがあり、各インスタンスはさまざまな最小値と最大値が指定された入力信号を使用する場合、この最適化によってサブシステムごとに異なるコードが生成されて、コードを再利用できなくなる可能性があります。この最適化を行わない場合、Simulink Coder™ ソフトウェアはサブシステムのコードを一度だけ生成し、そのコードをサブシステムの複数インスタンス間で共有します。

指定された最小値と最大値を使用した不要なユーティリティ関数の排除

この例では、Fixed-Point Designer ソフトウェアが除算の入力範囲を使用して、生成コードから不要なユーティリティ関数を排除できるかどうかを判断する方法を示します。ここでは fxpdemo_min_max_optimization モデルを使用します。最初に、指定した最小値と最大値を使用せずにコードを生成して、生成コードにゼロ除算を確実に防止するユーティリティ関数が含まれているかどうかを調べます。次に、最適化を有効にしてからコードを再度生成します。最適化により、生成コードにはそのユーティリティ関数が含まれなくなります。この関数は入力範囲には不要だからです。

最小値および最大値を使用しないコードの生成

最初に最適化を行わないコードを示すため、除算の最初の入力で設計の最小値と最大値を考慮しないでコードを生成します。この場合、2 つの入力の表現可能な範囲が使用されます。これらの入力はいずれも uint16 です。これらの入力範囲で、シフトを使用して指定された精度で除算を行うことはできません。そのため生成コードには除算ユーティリティ関数が含まれます。

  1. 例を実行します。MATLAB® コマンド ラインで次のように入力します。

    openExample('fixedpoint/FixedPointOptimizationsUsingSpecifiedMinAndMaxValuesExample')

  2. 例のウィンドウで、[View Optimization Configuration] ボタンをダブルクリックします。

    [コンフィギュレーション パラメーター] ダイアログ ボックスの [最適化] ペインが表示されます。

    [指定した最小値と最大値を使用した最適化] パラメーターの選択が解除されていることに注意してください。

  3. [コード生成] ボタンをダブルクリックします。

    コード生成レポートが表示されます。

  4. モデルで Division with increased fraction length output type ブロックを右クリックします。

    コンテキスト メニューが表示されます。

  5. コンテキスト メニューから [C/C++ コード][C/C++ コードに移動] を選択します。

    コード生成レポートでこのブロック用に生成されたコードが強調表示されます。生成コードにはユーティリティ関数 div_repeat_u32 への呼び出しが含まれます。

    rtY.Out3 = div_repeat_u32((uint32_T)rtU.In5 << 16, 
      (uint32_T)rtU.In6, 1U);

  6. div_repeat_u32 リンクをクリックしてユーティリティ関数を表示します。この関数にはゼロ除算を扱うためのコードが含まれています。

最小値および最大値を使用したコードの生成

次に同じ除算のコードを生成しますが、今度は Product ブロックの最初の入力の設計の最小値と最大値を考慮します。これらの最小値と最大値は Product ブロックのすぐ上流にある Inport ブロックで指定されます。このような入力範囲が指定されているので、シフトを使用するだけで生成コードは除算を行います。除算ユーティリティ関数を生成する必要がないので、メモリ使用量が減り実行時間が短縮されます。

  1. 5 というラベルの Inport ブロックをダブルクリックして、[ブロック パラメーター] ダイアログ ボックスを開きます。

  2. [ブロック パラメーター] ダイアログ ボックスで [信号属性] ペインを選択します。以下のことに注意してください。

    • この信号の [最小] 値は 1 です。

    • この信号の [最大] 値は 100 です。

  3. [OK] をクリックしてダイアログ ボックスを閉じます。

  4. [View Optimization Configuration] ボタンをダブルクリックします。

    [コンフィギュレーション パラメーター] ダイアログ ボックスの [最適化] ペインが表示されます。

  5. このペインで [指定した最小値と最大値を使用した最適化] パラメーターを選択し、[適用] をクリックします。

  6. [コード生成] ボタンをダブルクリックします。

    コード生成レポートが表示されます。

  7. モデルで Division with increased fraction length output type ブロックを右クリックします。

    コンテキスト メニューが表示されます。

  8. コンテキスト メニューから [C/C++ コード][C/C++ コードに移動] を選択します。

    コード生成レポートでこのブロック用に生成されたコードが強調表示されます。今回は、生成コードはシフト演算を使用して除算を行うので、除算ユーティリティ関数はありません。

    tmp = rtU.In6;
    rtY.Out3 = (uint32_T)tmp == 
      (uint32_T)0 ? MAX_uint32_T : ((uint32_T)rtU.In5 << 17) /
        (uint32_T)tmp;

指定された最小値と最大値の変更

最後に、値がシフトされたときにオーバーフローしないことを保証できなくなるほど入力範囲が大きくなるように除算の最初の入力の最小値と最大値を変更します。ここで、16 ビット数を右に 17 ビットだけシフトすると、32 ビット コンテナーから必ずオーバーフローします。最小値と最大値を考慮して、除算のコードを生成します。このような入力範囲が指定されているので、生成コードにはオーバーフローの発生を確実に防止するための除算ユーティリティ関数が含まれます。

  1. 5 というラベルの Inport ブロックをダブルクリックして、[ブロック パラメーター] ダイアログ ボックスを開きます。

  2. [ブロック パラメーター] ダイアログ ボックスで、[信号属性] ペインを選択し [最大値]40000 に設定し [OK] をクリックしてダイアログ ボックスを閉じます。

  3. [コード生成] ボタンをダブルクリックします。

    コード生成レポートが表示されます。

  4. モデルで Division with increased fraction length output type ブロックを右クリックします。

    コンテキスト メニューが表示されます。

  5. コンテキスト メニューから [C/C++ コード][C/C++ コードに移動] を選択します。

    コード生成レポートでこのブロック用に生成されたコードが強調表示されます。生成コードにはユーティリティ関数 div_repeat_32 への呼び出しが含まれます。

    rtY.Out3 = div_repeat_u32((uint32_T)rtU.In5 << 16, 
      (uint32_T)rtU.In6, 1U);