VX_FP_TASK は、タスク コンテキスト スイッチに FP レジスタを含めるよう強制します。これにより、コンテキストの切り替え時間が長くなります。アプリケーションの時間内に、このオーバーヘッドがあっても締め切りとパフォーマンスの目標を達成できる場合は、これを行うことにほとんど問題はありません。VX_FP_TASK がないことは、必要な場合にのみ注意して適用される最適化と見なされる場合があります。したがって、デフォルトのケースで VX_FP_TASK を使用する場合は、パフォーマンスを最適化する必要があるいくつかのケースで実行するチェックがおそらく少なくなります。多くの場合、必要な結果を得るために最適化は不要です。これが課すコンテキスト スイッチのパフォーマンス オーバーヘッドがプロジェクトの成否を左右する場合は、いずれにせよ限界に達する可能性があります。
一方、組み込みシステムでは FPU がより一般的になりつつありますが、従来はハードウェア FP がサポートされていなかったため、組み込みシステムの設計者がルールではなく例外として FP を使用することも一般的です。したがって、解決策の 1 つは、正式な正当化と承認なしに浮動小数点を使用してはならないという社内の設計規則を定めることです。つまり、浮動小数点の使用は、プログラマーの決定ではなく、設計で行う必要があります。チェックは、一般に、ソースをスキャンしてfloat
、double
、およびを探す単純なケースですmath.h
。(コード内でこれらのいずれかが発生しない限り、浮動小数点を使用することはおそらく難しいため)。たとえば、これらを探して警告を出すビルド前の静的解析チェックを追加できます。
多くのアプリケーションでは、FP 演算が自然に特定のタスクに限定されるように設計することができます。ただし、誰かがこれらのタスクのいずれかで使用することを意図した既存の関数を、FP セーフではない別の関数で使用することを選択すると、問題が発生します。これを見つけるのは難しいかもしれません。これに対する解決策は、浮動小数点を使用する関数を他のタスクで使用して、taskOptionsGet() を使用してタスク オプションをテストするデバッグ ASSERT を含めることです。
float
したがって、 、double
、およびの使用をスキャンし、math.h
これらを使用する関数に ASSERT チェックを追加することを組み合わせることで、コード メンテナンスでエラーが発生するのを防ぐことができます。
[2010Feb14追加]
複雑なマクロは一般的に悪いことですが、次のものが役立つ可能性があることをお勧めします (上記でほのめかしたように)。
#if NDEBUG
#define ASSERT_FP_SAFE() ((void) 0)
#else
#define ASSERT_FP_SAFE() do{ int opt; \
STATUS st = taskGetOptions( taskIdSelf(), &opt ); \
assert( st == OK && (opt & VX_FP_TASK) != 0 ) ; \
}while(0) ;
#endif
このマクロは、float または double を使用する関数、または使用する可能性のある他の FP 依存ライブラリ (テキスト検索で達成できる) を含む関数に挿入する必要があります。そのような関数が非 FP タスクから呼び出されると、アサーションは失敗します。
taskGetOptions() からの戻り値のチェックにより、割り込みコンテキストでの浮動小数点の使用がキャッチされることに注意してください。ただし、アサートが割り込みで発生した場合、出力が得られない場合があります。おそらく logMsg() への呼び出しの方が安全かもしれません。st != OK の場合はそれを使用でき、それ以外の場合は assert() を使用できます。
残念ながら、これは実行時のアサーションであるため、チェックするにはコードを実行する必要があります。静的解析で検出できれば良いのですが、簡単な方法が思い浮かびません。ただし、コード カバレッジ分析も使用する場合は、これで十分な場合があります。すべてのタスクを VX_FP_TASK にすることを選択したとしても、それは良い習慣かもしれません。そうすれば、誰かがどちらかを忘れたとしても、それを捕まえるチャンスがあります。