実行速度の遅いiwup_tsk2010年02月07日 00時46分16秒

現在開発に携わっている案件でμITRONを使っています。

このμITRONのiwup_tsk()が異常に遅い。 クロック周波数などは伏せますが、割り込みハンドラ内での実行速度に5us~80usというように幅がある。 サービスコールの前後でポートに出力してオシロスコープで観測した結果です。

私の認識ではiwup_tskはμITRONのサービスコール(システムコール)のなかでも最上級でシンプルで実行速度が速いつもりでいました。この認識を覆す遅さです。

遅いというよりも実行速度に幅があることが問題。こんなに幅があると割り込みハンドラの設計が出来ない。割り込み保留可能時間を見越せないということで非常に問題があります。

これは開発担当者の実装設計がまずいといわざるを得ないです。

私の認識では「iつきサービスコール」は以下のような実装である必要があると思っています。

  • 遅延ディスパッチは当然
  • 遅延ディスパッチの前の事前のキュー繫ぎ替え処理は関数本体では行わない
  • 関数本体では要求のためのマークをつけるだけ
  • キュー繫ぎ替え、割り込み復帰時のディスパッチ用のスタック操作は遅延ディスパッチ処理の一環として実施

実行速度に幅がある理由は想像では以下です。

  • 関数本体で遅延ディスパッチの事前準備まで実施
  • つまりレディキュー、待ちキューの繫ぎ替え処理まで行っている
  • 処理時間の違いはキューに繋がっているタスクの数に依存
  • キュー繫ぎ替えの結果によってディスパッチするタスクが割込みが入る以前のタスクかそうでないかによってコンテキストの扱いが変っている

遅延ディスパッチの実装上の意味を割り込みハンドラから抜けるタイミングまで遅らせて次の実行タスクにジャンプする程度のことだと勘違いしていないですかね。開発担当者は。

例えばサービスコール発行が一つではなく、複数の場合はこの実装だと処理時間の無駄が積算されます。

まあ、そんなに単純な理由ではないのかもしれませんけど。 ソースコード見ないことには真相は不明です。

いずれにしてもこんなに性能が悪いμITRONが出回っているのだとするとμITRONを使用したシステムの基本設計の最初の段階でサービスコールの実測作業が必要だということになります。 特に「iつきサービスコール」については実測必須です。 μITRONが速いということも主張できなくなりますね。

・・・・というところまで書いてきて、検索してたら使っているものとは違いますがdoxygenでTOPPERSのソース公開されているところを見つけました。結論としてはTOPPERSの実装が諸悪の根源みたいです。

これを見るとiwup_tsk()とwup_tsk()の実装はほぼ同じ。iwup_tsk()ではディスパッチを実行せずにディスパッチが必要かどうかのフラグを立てているところが違う。 だめじゃん。もっと前の段階の処理を省略しないと処理速度が一定にならないです。ディスパッチが必要かどうかを判定する処理自体も遅延させないと。つまり「wait_complete(tcb)」って関数コールはここでやったらだめです。キューの状態に依存する処理は処理速度が一定にならないですから。

こちらにも解説がありますね。

このような状況が放置されているのは最近のμITRONのカーネルの開発者と実際の組込みシステムの開発者の意識が違いすぎるということなのかもしれません。μITRON2.0の時代は現場の人間がμITRONカーネルの開発をしたので学者じゃなかったと思います。

今のμITRONカーネル開発者は「学者」ってことです。本当の性能要件が分かっていない。 割り込みハンドラの実装部分から設計をやり直したいですね。 メモリ保護とかよりもこっちが先でしょ。

コメント

_ R32C ― 2010年04月24日 16時33分08秒

某メーカーのμITRONのカーネル実装をやっているものです。
指摘事項は、なるほどと思うこともあり、参考にしたいと思います。
実際に性能目標は、wup_tsk()のディスパッチャを含めたタスクの
切り替え時間にしているというのはあります。

>•遅延ディスパッチの前の事前のキュー繫ぎ替え処理は関数本体では行わない
>•関数本体では要求のためのマークをつけるだけ
アイデアとしてはいいと思います。

ただそれをするとディスパッチを含めた性能の問題
サービスコールの不可分性の保証をどう実現するか

ということが大変難しくなるとは思います。
単純に考えると100回以上リクエスト(たとえばタスクが100個あった場合)があった場合に遅延ディスパッチで
100回分処理することになるわけですね。


ご指摘のように最大割り込み禁止時間についてですが、
そのμITRONの場合の実装が何かはわかりませんが、自分のやっているものでは
割り込み禁止時間そのものはそれほど大きくばらつきません。
理由は、キューの長さ等によって処理時間が前後するサービスコール
では、途中で割り込みをあける処理を入れるためです。

ただ、iwup_tskは、レディキューに並べる処理なので、レディキューの処理として
キューの長さによって処理時間がばらつくことはないのが普通です。

>•処理時間の違いはキューに繋がっているタスクの数に依存
これは間違いです。
レディQは優先度別にそれぞれQヘッダがあり、iwup_tsk()でのキューの繋ぎ換えは、
Qの最後に繋ぐ処理なので長さに依存しません。ただ、まったくその優先度に
レディタスクがない場合と処理時間は多少違いはします。

最近はマニュアル記載はやめましたが、内部データとして、サービスコール毎の
処理時間と最大割り込み禁止時間のデータはとっています。ユーザが要求があったら
だせるようにしているとのことです。
他社はわかりませんが、必要なら開発元に資料の提出を求めても
いいかもしれません。

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
このブログでは「組込み」と「組み込み」のどちらを使っている?

コメント:

トラックバック

このエントリのトラックバックURL: http://kumikomi.asablo.jp/blog/2010/02/07/4862978/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。