(toppers-users 3795) 2つの優先度の最適な利用方法は?

kazuhiro takahashi takahashi_kazuhiro @ nifty.com
2012年 1月 19日 (木) 23:16:01 JST


こんばんは、アライブビジョンソフトウエアの高橋です。

厳しい回答がされているようなのですが、「美しい」とか「でたらめ」など
なかなか伝わりにくい表現をされているようですが、自分はこいさんさんの
ご意見はなんとなくわかる気がします。

実際にSSPの省メモリ(省スタック)でタスク設計を行う場合に
従来のITRONの考え方での設計だけでは、不十分で新しい手順が必要になると考えています。

考え方が難しいのは、2つのタスクの2種類の優先度が挟まったような状態
のときですね。 2パターンあり、含まれるケースと互い違いになるケースかと思います。
結局、いずれのパターンも両方の実行時優先度は両方の起動時優先度より優先度が高く
なります。 つまり、お互いにプリエンプトされないものになります。
どちらのタスクが実行されるかは、起動時優先度が絶対ではなく、起動の順番と、どこ
(どのタスク)から起動されるかによって変わると思います。
つまり、起動されるパターンが一定のタスク群の条件によらない場合、たとえば
割り込みハンドラからの起動の場合には、どちらのタスクが優先的に動くか不定
ではないかと思います。 これが何か誤解があれば指摘いただければ
幸いですが、そのとおりなら、これを「美しくない」と思うのは同意できます。

ただこういったテレコの優先度の場合は、プリエンプトされない関係にあるので
スタックサイズをどちらかの最大値にできるので省メモリには有効になり、
いつどれだけ動くかについては、同一優先度のものと考えたら考えやすいように
思いますが、ただこれには落とし穴があると思います。

例をあげてみます。

タスクの優先度の低いものの3つのタスクがあり、これは割り込みハンドラ
からそれぞれ、フラグとFIFOとタスク起動されるタスクa,タスクb,タスクcがあるとします。
タスクa,b,cの実行時優先度を同一にします。同一にする理由は同一スタックを利用するためです。
だいたい満遍なく実行される取りこぼししてもいい処理を行うタスクとします。
(同一実行時優先度以外でもスタック同一化は可能ではありますが、とりあえず例はそうします。)

実行時優先度は、最低の16とし、起動時優先度はタスクa,b,cそれぞれ、5,6,7 とします。
さらに上位のタスクが4つあるものとします。起動時優先度と実行時優先度が同じでそれぞれ1〜4の優先度
をもちます。

タスクa,b,cの負荷は、上位タスクがまったく動かなければ問題ないが、
上位タスクが動いた場合は、過負荷になり、FIFOキューがかなり溜まるようなシステム
となっていたとします。

こういった場合、これが期待通りに動いてくれないと思います。
FIFOが溜まりだしたら、タスクa,b,cのうちどれかばかり動く可能性があります。
なにかVisualBasicのDoEventsのような協調的マルチタスクまがい
の動作になるように思います。

だいたい、過負荷のタスクが複数あることが問題ですが、普通の設計なら
a,b,c優先度つけて、bやcが走りきらないことをあきらめるという設計になると思います。
つまり、プリエンプトされる関係にすることになります。
最も省メモリにはこのケースは使えないことになります。


それでは、SSPの省スタックにするためには同一実行時優先度が使えるケースとはどんな
ケースがあるのかということを考えると上記のようにCPUの稼働率が高い場合には
どれだけ動くか予測が難しく利用できないように思います。
なので、省メモリとCPUの負荷のバランスがとる必要があると思います。
リアルタイムシステムにおいて負荷は変動するので、安易に利用すると思わぬ
不具合になると思います。

思い違いをしていれば、ご指摘いただければ幸いです。


On Thu, 19 Jan 2012 18:58:03 +0900
Naoki Saito <nsaito.nmiri @ gmail.com> wrote:

> 斉藤です.
> (toppers-users 3788) を確認したという前提の元で,お返事します.
> 
> > TASK3が動作しているときはTASK4が動かず、
> (略)
> >  これが意図とでは優先度とは何よと思いたくなるのは、私だけでしょうかね。
> 
> 逆に.優先度とはどのようなものと思われたのか,興味を持ちました.
> 
> 例として仰られたようなケースは一つの使い方でして,
> そのような挙動をさせたいというケースもないとはいえないです.
> 例えば (toppers-users 3781) で高田先生が仰られた様な
> スタック領域が少なくて済むようにしたいというのもその一つかと思います.
> 排他制御のためにそうしたいという理由もあると思います.
> 
> >  どちらのタスクが優先度が高いのかと一言で表現できないのは、美しくないと思います。やる人はいないと思うが、もっと複雑な(誤った?)設定をした場合、優先度がでたらめになりませんか。
> 
> 最初の文に対して,
> 美しいかどうかは主観的な評価なのでなんとも申し上げることは出来ませんが
> 仰るような考え方によりますと,動的に優先度が変更し得るOSは皆美しくない
> ことになりますね.そういう理解で合ってますでしょうか?
> 現存するOSはそういうものも割と多いと思いますが,どう思われます?
> 
> 2番目の文に対しては,当然でたらめになり得ます.
> しかしそれは使い方次第です.どんなむちゃくちゃなプログラムを書いても
> ちゃんと動けというのはそりゃムリです.
> 
> 以上,適切なお答えになっているか心配ですが,よろしくお願いします.
> 
> 2012年1月19日16:15 koizumi yoshiyuki <koizumiyoshiyuki @ gmail.com>:
> >  こいさんです
> >
> >  理屈としては解るのですが、この場合
> > TASK3が動作しているときはTASK4が動かず、
> > TASK3が動作しているときはTASK4が動きません。
> >  これが意図とでは優先度とは何よと思いたくなるのは、私だけでしょうかね。
> >
> >  どちらのタスクが優先度が高いのかと一言で表現できないのは、美しくないと思います。やる人はいないと思うが、もっと複雑な(誤った?)設定をした場合、優先度がでたらめになりませんか。
> >
> >  まあ、意図なら納得するしかありません。
> >
> >  以上
> >
> > 2012年1月19日15:39 Naoki Saito <nsaito.nmiri @ gmail.com>:
> >>
> >> こいさんさん
> >>
> >> 斉藤です.
> >>
> >> >  現行のSSPのCFGで以下の設定をすると、優先度反転が発生します。これは良いのでしょうか。
> >> >  TASK3が動作中にTASK4はTASK3より優先度が高いのに起動できません。
> >>
> >> TASK3 の実行時優先度は4で,TASK4の起動時優先度は6ですので
> >> TASK4 は TASK3 より優先度が低い(数値としては大きい)です.
> >> したがってTASK4 が起動出来ないのは仕様に沿っているように思います.
> >>
> >> >  CFGで生成されたkernel_cfg.cは以下のようになり、TASK3とTASK4の優先度の反転が発生しています。
> >> >
> >> > const uint_t   _kernel_tinib_epriority[TNUM_TSKID] =
> >> >
> >> > {INT_PRIORITY(1),INT_PRIORITY(2),INT_PRIORITY(3),INT_PRIORITY(4),INT_PRIORITY(4),INT_PRIORITY(3)};
> >>
> >> これは実行時優先度を格納する配列です.
> >> プリエンプトが発生するかどうかは
> >> 実行中タスクの実行時優先度と起動要求タスクの起動時優先度とを
> >> 比較します.従いまして,TASK4 の実行時優先度はこの場合参照されません.
> >>
> >> 以上,よろしくお願いします.
> >>
> >> 2012年1月19日10:59 koizumi yoshiyuki <koizumiyoshiyuki @ gmail.com>:
> >> >    高田先生
> >> >
> >> >  こいさんです。表現は色々有ると思いますが、私にはSSPは優先度を2つ持っているように見えています。
> >> >  2つの優先度は _PRIORITY >_EXEPRIORITY 設定されてる必要が有るでしょう。これは解りにくいケースもあると思います。
> >> >
> >>
> >> > >  同じようなケースが(私にはある意味、同じように見えています)Cortex-M3の割り込み優先度に見られます。ここでは優先度を上位/下位の2つに分け、上位側で横取り割り込み優先度とし、下位側は等優先度内(制約タスク相当)の優先度としています。外からは優先度は一つしかないので優先度設定の混乱を避けることができていると思います。
> >> >
> >> >  尚、
> >> >  現行のSSPのCFGで以下の設定をすると、優先度反転が発生します。これは良いのでしょうか。
> >> >  TASK3が動作中にTASK4はTASK3より優先度が高いのに起動できません。
> >> >
> >> >  テストタスクを3つから4つに増やし優先度を以下のように設定する
> >> >
> >> >  sample1.h
> >> > #define INIT_PRIORITY   (1)
> >> > #define MAIN_PRIORITY   (2)
> >> > #define TASK1_PRIORITY   (3)
> >> > #define TASK2_PRIORITY   (4)
> >> > #define TASK3_PRIORITY   (5)
> >> > #define TASK4_PRIORITY   (6)
> >> > #define TASK3_EXEPRIORITY  (4)
> >> > #define TASK4_EXEPRIORITY  (3)
> >> >
> >> >  sample1.cfgを以下のように記述
> >> > CRE_TSK(INIT_TASK , { TA_ACT , 0 , init_task , INIT_PRIORITY ,
> >> > STACK_SIZE ,
> >> > NULL });
> >> > CRE_TSK(MAIN_TASK , { TA_NULL , 0 , main_task , MAIN_PRIORITY ,
> >> > STACK_SIZE ,
> >> > NULL });
> >> > CRE_TSK(TASK1 , { TA_NULL , 1 , task , TASK1_PRIORITY , STACK_SIZE ,
> >> > NULL
> >> > });
> >> > CRE_TSK(TASK2 , { TA_NULL , 2 , task , TASK2_PRIORITY , STACK_SIZE ,
> >> > NULL
> >> > });
> >> > CRE_TSK(TASK3 , { TA_NULL , 3 , task , TASK3_PRIORITY , STACK_SIZE ,
> >> > NULL
> >> > });
> >> > CRE_TSK(TASK4 , { TA_NULL , 4 , task , TASK4_PRIORITY , STACK_SIZE ,
> >> > NULL
> >> > });
> >> > DEF_EPRI(TASK3 , { TASK3_EXEPRIORITY });
> >> > DEF_EPRI(TASK4 , { TASK4_EXEPRIORITY });
> >> >  CFGで生成されたkernel_cfg.cは以下のようになり、TASK3とTASK4の優先度の反転が発生しています。
> >> >
> >> > const uint_t   _kernel_tinib_epriority[TNUM_TSKID] =
> >> >
> >> > {INT_PRIORITY(1),INT_PRIORITY(2),INT_PRIORITY(3),INT_PRIORITY(4),INT_PRIORITY(4),INT_PRIORITY(3)};
> >> >  以上
> >
> >


-- 
kazuhiro takahashi <takahashi_kazuhiro @ nifty.com>