[openrtm-users 01357] Re: high CPU load when deactivate python component

Masayuki Shimizu masayuki.shimizu @ aist.go.jp
2010年 7月 6日 (火) 23:53:34 JST


安藤様

清水です。

> #別の実装としては、ECのactivate_component()
> などの呼び出しから、
> #現在アタッチされているRTCの状態がInactiveかどうかをEC
自体が常に補足
> #するという方法もありますかね?

私が考えていたのは、こちらの方法で、
毎周期RTCの状態を調べる必要はありません。

RTCの状態遷移図によると、
以下のようになっています。

・INACTIVE -> ACTIVEの状態遷移は、
activate_component()をトリガーとして発生する。

・ACTIVE -> INACTIVEの状態遷移は、
deactivate_component()をトリガーとして発生する。

・ERROR -> INACTIVEの状態遷移は、
reset_component()をトリガーとして発生する。

これより、ECをstart/stopするタイミングは、
上記のメソッドが呼ばれた時だけになると思います。
したがって、上記メソッドの内部で
RTCの状態をチェックしECをstart/stopすれば、
最小限の負荷で、RTCの状態とECのstart/stopを
連動させることができると考えたわけです。

また、少々手間ですが、RTCの状態とECのstart/stopを
連動させるかどうかをconfで指定できると
ベストかと思います。

ご検討の程、よろしくお願いいたします。

清水

--- Ando Noriaki <n-ando @ aist.go.jp> wrote:

> みなさま
> 
> 安藤です
> 
> ほぼ栗原さんからの返答で言い尽くされていると思いますが
少し補足を。
> 
> ECとRTCの関係ですが、PeriodicExecutionContext::svc()
> がまさに
> その部分になるかと思います。
> 
>     do
>       {
>         m_worker.mutex_.unlock();
>         while (!m_worker.running_)
>           {
>             m_worker.cond_.wait(); //
> stopped状態のときここで待つ
>           }
>         if (m_worker.running_)
>           {
>             std::for_each(m_comps.begin(),
> m_comps.end(),
> invoke_worker()); // すべてのRTCのアクションを実行
>           }
>         m_worker.mutex_.unlock();
>         if (!m_nowait) { coil::sleep(m_period); }
>       } while (m_svc);
> 
> 
> invoke_worker()
> の中身ですが、コンポーネントの現在の状態の
> アクション (on_何とか)
> を実行するものだと思ってください。
> なお、Inactive
> 状態は、on_何とかに相当する関数がないので
> ダミーの空の関数が実行されていると思ってください。
> 
> do-while の for_each
> の部分を書き下すと、コンポーネントがそれぞれ以下の状態
にある場合
> 
> RTC0: inactive
> RTC1: active
> RTC2: active
> RTC3: error
> 
> do-while の for_each 内
>  RTC0. dummy();
>  RTC1: on_execute();
>  RTC2: on_execute'(;
>  RTC3: on_error();
> 
> ということになります。したがって、RTC0がinactive状態で
すが、
> ループを止めるわけにはいきません。
> 
> 清水さんがおっしゃるように、すべてのRTCがinactiveの場
合は
> ループを止めてもいいのですが、そうなると、
> #以下適当なコードですが、
> 
>     do
>       {
>         m_worker.mutex_.lock();
>         while (!m_worker.running_)
>           {
>             m_worker.cond_.wait(); //
> ECのstopped状態のときにここで止まってる
>           }
>         if (m_worker.running_) //
> ECがrunning状態のとき
>           {
>             m_inactivewait.mutex_.lock();
>             inactivecomps =
> for_each(m_comps.begin(), m_comps.end(),
> Inactivecomps()); // (1) Inactiveかどうか調べる
>             while (inactivecomps.num() ==
> m_comps.size()) {
> m_inactivewait.cond_.wait(); } // (2)
> 全部inactiveならwait
>             std::for_each(m_comps.begin(),
> m_comps.end(),
> invoke_worker()); // (3) 各RTCのアクションを実行
>             m_inactivewait.mutex_.unlock();
>           }
>         m_worker.mutex_.unlock();
>         if (!m_nowait) { coil::sleep(m_period); }
>       } while (m_svc);
> 
> 
> という感じで、毎周期すべてのコンポーネントを調べる必要
があります。
> #別の実装としては、ECのactivate_component()
> などの呼び出しから、
> #現在アタッチされているRTCの状態がInactiveかどうかをEC
自体が常に補足
> #するという方法もありますかね?
> 
> この部分は、リアルタイム実行される可能性もあるので、こ
れを
> 取り込むかどうかは (1) の for_each
> がどのくらいの時間がかかるかにもよると思います。
> あと、ロックが追加されている部分と、ECのもうひとつの状
態遷移(stopped<->running)
> との兼ね合いについてもよく考える必要があります。(デッ
ドロックが起こらないかどうかなど)
> 
> というわけですので、今後の検討課題とさせてください。
> 
> 
> 
> 
> 2010年7月6日19:15 kurihara shinji
> <shinji.kurihara @ aist.go.jp>:
> > 松坂様
> >
> > 栗原です。
> >
> >
> 以下は、一つのExecutionContextに対して複数のRTCが登録
された場合についてです。
> >
> >> ・ExecutionContextは直列リストの構造をしている。
> >
>
ExecutionContextは、add_component(rtobj)にて登録されたRTC
をリストで管理してお
> >
> り、whileループの中では、リストに登録されているRTCのア
クティビティ処理を呼び出し
> > ます。(正確には、StateMachineから呼ばれます。)
> >
> >>
> ・ただし、あくまで分散コンポーネントモデルなので中央で
コンテキストを管理している
> >>
> サービスがあるわけではなく、各コンポーネント同士がバケ
ツリレーのような形で
> >> 実行タイミングを通知しあっている。
> >
> RTCのリストに登録してある順番でRTCのon_execute()などを
呼びますので、たとえば、
> >
> 3つのRTC(A,B,C)が登録されていて、3つのRTCがACTIVE状
態であれば、Aのon_execute
> >
> ()が戻ってきて、Bのon_execute(),Cのon_execute()のよう
になります。
> >
> よって、各コンポーネント同士が実行タイミングを通知しあ
っているのではなく、
> >
> あるRTCのアクティビティ処理が終了次第、次のRTCのアクテ
ィビティ処理の実行をECが
> > 行うといった仕様になっております。
> >
> >
> > 以上、宜しくお願い致します。
> >
> >
> > On Tue, 6 Jul 2010 17:44:54 +0900
> > Yosuke Matsusaka <yosuke.matsusaka @ aist.go.jp>
> wrote:
> >
> >> 栗原さん
> >>
> >> 松坂です。
> >>
> >> 2010/7/6 kurihara shinji
> <shinji.kurihara @ aist.go.jp>:
> >> >
> RTMでは、一つのExecutionContextで複数のRTCを駆動する事
が可能となっております。
> >> >
> 仮に、非アクティブ状態でループを回さないようにした場合
、一つのECに複数のRTC
> >> > が関連付けられてる状況において、一つの RTC
> が非アクティブ状態の時に、他のアク
> >> >
> ティブ状態のRTCまでも駆動関数(on_execute)が実行されな
いといった事になってしまい
> >> > ます。
> >> >
> >> >
> 上記のような理由もあり、ExecutionContextのループは、RTC
の状態に関わらずループ
> >> > する仕様となっております。
> >>
> >> なるほど、理解しました。
> >>
> 金広さん、清水さんの議論を読んで、何となく私の理解がず
れている予感がしていたのですが、
> >> これでクリアになりました。
> >>
> >> ・ExecutionContextは直列リストの構造をしている。
> >>
> ・ただし、あくまで分散コンポーネントモデルなので中央で
コンテキストを管理している
> >>
> サービスがあるわけではなく、各コンポーネント同士がバケ
ツリレーのような形で
> >> 実行タイミングを通知しあっている。
> >>
> >> というわけですね。
> >>
> 改良しようとしてもなかなか難しいところですね、、、。
> >>
> >> --
> >> Yosuke Matsusaka, Ph.D 
> <yosuke.matsusaka @ aist.go.jp>
> >>   Interaction Modeling Group /
> >>   National Institute of Advanced Industrial
> Science and Technology (AIST)
> >>   Tel: 029-862-6726  Web:
> http://staff.aist.go.jp/yosuke.matsusaka/
> >>
> >
> >
> > --
> > ----------
> > 栗原 眞二 <shinji.kurihara @ aist.go.jp>
> >
> > 独立行政法人産業技術総合研究所
> >  知能システム研究部門 統合知能研究グループ
> >  〒305-8568
> >  茨城県つくば市梅園1-1-1 中央第2
> >
> >  TEL: 029-861-5956
> >
> >
> 
> 
> 
> -- 
> 安藤慶昭@独立行政法人産業技術総合研究所
> 知能システム研究部門
>     統合知能研究グループ 主任研究員, 博士(工学)
>     〒305-8568 つくば市梅園1-1-1 中央第2
>     e-mail: n-ando @ aist.go.jp, web:
> http://staff.aist.go.jp/n-ando
>     OpenRTM-aist: http://www.openrtm.org
> 
> 




openrtm-users メーリングリストの案内