5

vxworks では、すべてのタスクを VX_FP_TASK オプションで生成する必要がありますか?

タスクで浮動小数点演算を使用する場合は、VX_FP_TASK オプションが必要です。しかし、どのようにして未来を予測するのでしょうか? つまり、float を使用するかどうかをどうやって知ることができるのでしょうか?

バグを修正したり、新しいコードを導入したりする際に、プログラマーは自分のコード変更によってどのすべてのタスクが影響を受けるか、またそのタスクがこのオプションで生成されるかどうかを確認する必要がありますか? これは非常に面倒です。何か不足していますか?

4

3 に答える 3

6

VX_FP_TASK は、タスク コンテキスト スイッチに FP レジスタを含めるよう強制します。これにより、コンテキストの切り替え時間が長くなります。アプリケーションの時間内に、このオーバーヘッドがあっても締め切りとパフォーマンスの目標を達成できる場合は、これを行うことにほとんど問題はありません。VX_FP_TASK がないことは、必要な場合にのみ注意して適用される最適化と見なされる場合があります。したがって、デフォルトのケースで VX_FP_TASK を使用する場合は、パフォーマンスを最適化する必要があるいくつかのケースで実行するチェックがおそらく少なくなります。多くの場合、必要な結果を得るために最適化は不要です。これが課すコンテキスト スイッチのパフォーマンス オーバーヘッドがプロジェクトの成否を左右する場合は、いずれにせよ限界に達する可能性があります。

一方、組み込みシステムでは FPU がより一般的になりつつありますが、従来はハードウェア FP がサポートされていなかったため、組み込みシステムの設計者がルールではなく例外として FP を使用することも一般的です。したがって、解決策の 1 つは、正式な正当化と承認なしに浮動小数点を使用してはならないという社内の設計規則を定めることです。つまり、浮動小数点の使用は、プログラマーの決定ではなく、設計で行う必要があります。チェックは、一般に、ソースをスキャンしてfloatdouble、およびを探す単純なケースです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 にすることを選択したとしても、それは良い習慣かもしれません。そうすれば、誰かがどちらかを忘れたとしても、それを捕まえるチャンスがあります。

于 2010-02-12T09:51:45.077 に答える
3

経験から、私は簡単な答えを与えることができます:常にVX_FP_TASK でタスクを生成します。特に、コードをさまざまなアーキテクチャで使用できる場合。

コンパイラ (gnu、diab)、使用するコンパイル フラグ、およびアーキテクチャに応じて、浮動小数点レジスタは浮動小数点演算以外にも使用できます。ほとんどのアーキテクチャでは、FP レジスタは通常のレジスタよりも大きいため、コードを最適化するための最適な候補になります。

たとえば、PPC603 プロセッサでは、単純な C の代わりに C++ を使用すると、最適化に FP レジスタが使用されます。そのタスクで VX_FP_TASK を有効にしていないと、別のタスクの FP レジスタが破損する可能性があります。計算をしないでください!

正しい実行はパフォーマンスよりも重要であり、ほとんどの場合、パフォーマンスの向上は、それを有効にしないことによってもたらされるリスクを正当化するものではありません.

すべてのタスクでフラグが有効になっていることを確認したい場合は、taskCreateHookAdd( ) を使用して、タスクの作成中に常にフラグを有効にするフックを追加することを検討してください。

于 2010-02-15T21:43:01.640 に答える
2

常に VX_FP_TASK を使用してください! それを持っていないこと、および結果として生じる不規則なエラーを追跡しようとすることのコストは、信じられないほど高価です.

于 2012-01-21T00:22:49.657 に答える