SWEST5議事録 分科会F4 組み込みソフトウェアのデザインパターン F会場 *注意  聞き落とし、書き落とし、意訳多数。  書き出すきっかけを逃した部分の抜け落ちが激しい。  話を追いかけるのに精一杯で、意味的な整合性まで考慮されていない。  書き取りの都合で語調は全て常体に変更してある。 ------------------------------------------------------------------------------- 大山: 組み込みソフトウェアのデザインパターンは2000年頃からCESTで始まった。組み込み ソフトウェアパターンには、非組み込みソフトウェアには見られないパターンがある。 皆さんにも経験があると思われるが、それらは結局文献で明らかになっている・あるい は整理されているとは言えない。そこで、整理することで技術者に有用な文献、教材を 作りたい。午前中に西さんが言ったように、教科書が10冊も挙げられないのが現状であ るので、この議論が何がしかの教材になればいいと思う。  デザインパターンと言うのは GOFの「デザインパターン」があって、これが火付け 役になった。この本自体は非組み込みのものであるが、これがきっかけであちこちのコ ミュニティでパターンを見つけようと言う動きが出てきた。この本自体の目的は、オブ ジェクト指向ソフトウェアのデザインパターンを記録することにある。デザインパター ンと言うのは、繰り返し現れるパターンを分類して名前を付けたもの。組み込みソフト ウェアの分野でもそういうものを作ろうということ。  これまでの取り組みと言うのは2001年頃からCESTで行ってきた。20社程度の企業が参 加しているが、分野に偏りがあるので、SWESTによって広い分野から企業が集まること を期待。優秀な技術者さんから良く使うパターンを挙げて欲しい。設計パターンとデザ インパターンは日本語しか違わない。私はそういうのをやろうと思っていたが、服部さ んがもっと泥臭い部分−プログラミング的な、目的の限られているものをやろうという ことになった。昨夜もっと違うパターンと言うのを議論したので、今日もいろいろなパ ターンを出して欲しい。  設計・実装パターンがあるといった。そのうち設計パターンの方はタスクスケジュー リング、バッファリング、エラー処理(以下スライドの例を読み上げ)。名前を聞くと 想像がつくものが多いと思う。このうち二つを説明する。  リターンリターンパターンはエラー処理のパターン。関数呼び出しに際し正常・異常 終了をチェックする。エラー値がリターンされると上位にまたリターンするのでリター ンリターン。構造は図を使いたいが、今回はコードで説明。func1を呼び出してfuncAが エラーをチェックし回復処理をする。何もなければ終了する。説明する必要がないくら い(明白な話である)。  ハーモニックタスクパターン。ハーモニックタスクと言うのは(書き落とし)スケジ ューリングの一つの特化したスケジューリングに対して付けられた名前。リアルタイム タスクにより効率の良い組み込みシステムを実現。(幾つかの話題、書き損じ)。実体 を見ればこんなのをやったなあと思ってもらえるだろう。タスクの周期がより短い周期 のタスクの倍数となる。この例は二つなので分かり辛いが、三つ目のタスクが出ると1 と2の倍数となる。  以上二つが設計のパターンであり、次は実装のパターンについて話す。 服部:  実装のパターンでは、皆さんが経験していてこんなのは別にパターンではないだろう というものでもとにかく言葉にして伝えていこうと言うこと。(以下スライドの例示パ ターンを順に読み上げ)というようなものを挙げている。スタートアップやメモリチェ ックに関するパターンと言ったものも挙げる。ROMの内容のチェックとかも文章に起こし つつある途中。そのうち2点を説明する。  エンディアン変換。組み込みで同じプロセッサを使っている限りは、ビッグだろうと リトルだろうと気にする必要さえない。しかし異なるプロセッサや通信が絡んできたと きにエンディアン方式が違うと問題になる落とし穴。対処法としてはマクロでシフトす るという方法が一般的。他にも色々ある。  タイマ/カウンタ。(書き落とし)理由が別に見つからない。実装方法としてはイン クリメント・デクリメントがある。時間の処理が複数の場合はインクリメント、処理が 一つで開始タイミングが複数の時はデクリメントにするといいのでは。いまだC言語の 256バイトメモリのような劣悪な環境もあるので、いかにカウンタ値を小さくするかが 問題になることもある。  今悩んでいるのは省電力に関する定義パターン。最近はバッテリー駆動式のものが増 えてきているので、必要のないときは停止させてバッテリーを長持ちさせたい。OSの ないような物の場合力技でHaltにしたりするのだが、OSがある場合どのようにするか はまとまっていない。このことに関する意見募集。  ここまでで事前まとめはおわらせて、メーリングリストで募集した意見を紹介する。 大山:  メーリングリストの宿題には3件の回答が得られた。二上さんのパターンは難しいの で後回しにしたい。ある人が経験したものを他の人も経験すれば、それはパターンであ ると言えるかもしれない。なんでもパターンになって幅広く取ることが出来る。 堀江:  初めてSWEST5に出席した。今日出したのはDSPの最適化に関するパターンで、最適化 アルゴリズム。日頃はDSP恐怖症を日本から払拭すべく活動。アセンブリで動かすのは 魔術ではない。  ソフトウェア・パイプラインパターンは有名で、これさえ知っていればDSPがつかえ る。やりかたとしてはループの最適化、ループの並列実行と言う形で最適化。DSPの特 徴というのは2〜3の命令を同時に実行する命令があること。慣れてないと根性で力押 ししてしまう。ソフトウェアパイプラインを使うと簡単。エクセルか何かのスプレッド シートが必要。ループを回数分展開する。このとき適当にずらす。何セルずらすかは経 験。例えばとりあえず3セルずらしてみる。並んだ命令ペアを同時に実行できるかどう か見る。めでたく実行可能であれば、長い新しいループボディが出来る。抽象的に言う とn回のループがn−1回のループになり、ループの長さが半分、幅が二倍になる。DSP では良く使われる考え方。パイプラインハードウェアとの類似性(?)。一番難しいの は並列な命令の実行がなるか否か。制約も勿論あるが、それはハードウェアパイプライ ンと同じ。ハードウェアはラッチを、ソフトウェアはレジスタを使う。ソフトウェアの レジスタも(欠落部分)。ソフトウェアパイプラインと言うのはループを展開しエクセ ルに斜めに貼っていき、命令が上手く実行できればk倍速になる。詳しくはWebページ にて。 大山:  場違いと言うのは。(初めて出席した、と言った時にそんなようなことを言った。) 堀江:  熱い会議と聞いていたので信号処理の話もでるかと思ったら出なかった。でも、来年 以降は布教に励もうと思う。 大山:  皆そういう意識は多少なりとも持っていると思う。自分の分野の話をどんどん出して 欲しい。それでは次の例。 堀江:  大抵の本の例題はソフトウェアパイプラインを使っている。もう一つ、ループアンロ ールパターンというのがある。名前には不勉強ゆえ自信がない。実際にはループアンロ ールとインターリーブという二つの方式を組み合わせたもの。簡単の為に仮想プロセッ サを考える。連続した命令も考える。(ホワイトボードに作図)熱いけど4分の3くら いはアイドルしてるだけ、というのがPentiumへの悪口。n回10命令のボディがあっ て、1サイクルのストールが入るようなプロセッサの場合、n/2回にしてボディを倍 にする。インターリーブで2枚の櫛の歯を重ね合わせるようにすると、各々のストール の無駄がなくなる。上手く行けば速度が上がる。問題は、2個の繰り返しにしてしまっ たループのボディはレジスタを共用できないと言うこと。下手を踏むとたちまち問題に なる。もう一つの制限は、DSP固有の事情と言うか、DSPでしか回避できない問題なのだ が、インデックスレジスタの共用問題。更新を1命令でやっていて、ループボディに一 回しか出てこない場合のみ上手く行って速度が上がる。 大山:  実はよくわからないかも。これは必ず使われるようなものなのか。 堀江:  最近では必ず出てくる。とはいえ、DSPはやはりマイナーなので、文献としてまとめら れてはいない。 大山:  (何か言ったらしいが全部欠落) 服部:  ソフトウェア的な最適化を言う人もいる。技科大の(聞き落とし)先生。最適化する 事によって全体のパフォーマンスが上がる。 不明:  CESTで市川先生がいらして、2回ほど話された。演算効果をあげる話とキャッシュの 効果の話。一番目の話、古典的DSPの話。私はYAMAHAだが、DSPでは専用のプロセッサを 如何に同時に動かすかが問題。最近のDSPではCでも書ける、みたいな話も聞くが、最 近のはどうか。 堀江:  最近のDSPの動向は、深いパイプライン化というのがあげられる。昔のは浅くて3〜 4段。最近になって各社覚悟を決め、少々ストールが起きてもいいから周波数を上げる ため7〜8段にした。600MHz程出るようになったが、代わりにストールが発生するよう になった。一応大抵回避できるようになった。2つ目には(欠落)がある。別の最適化 。私見だが、CでDSPの最適化は出来ないだろう。ボトルネックだけはアセンブリで書 くべき。割り込みハンドラあたりはC/C++でも良い。 大山:  アセンブリで書くべき物がある、という話か。 堀江:  今DSPで伸びているのは携帯のプロセッサ。これはガンガン発熱する。単位体積あたり の処理能力が求められるし、消費電力も抑えたい。 (次の発表者と交代) 萩原:  半導体工業研究の人。経験的に困ることの多かったのはヒープメモリの管理。組み込 みの場合やはりメモリが限られているので長時間の稼動でヒープが枯れたり、あとフラ グメントの問題。手っ取り早く単純に解決する方法を提案と言うより教えて欲しい。フ ラグメンテーションの回避でまず思いつくのはヒープじゃなくてスタティックに使用す るやり方。どうしても解放・確保をするなら同時期に使うものは同時期に確保・解放す るとフラグメンテーションが起こりにくい。3番目の方法は試したことはないが、サイ ズの大きいものと小さいものを別領域から取るようにすればいいのではないか。問題点 や効果については、試してないので意見募集。 大山:  リアルタイムアプリケーションではヒープを使わないのがパターンと言うより鉄則だ と思う。これ(ヒープ)はどんなアプリで使うのか。 萩原:  JAVAを使った時に困ったこと。JAVAのVMを作って配布した時、エンドユーザの方から VM上でアプリを2〜3ヶ月走らせるとメモリが枯れる、という問い合わせが何件か来た。 JAVAでは動的な確保が不可避で、フラグメンテーションは余程注意してアプリケーショ ンを作らない限り起こってしまう。全部JAVAならいいが、一部ネイティブでスタティッ クな確保を使われると困ったことになる。 不明:  サイズの大小を分ける手法で実装したことがある。今の話はメモリがたくさんある環 境のよう。JAVAのヒープが取るのとネイティブが取る領域を別々にしてしまえばいいの では。 萩原:  実際にやってみて逆に問題が出るようなことはあったか。 不明:  ヒープが要求するサイズが予想されているケースだったので参考にならないと思う。予 想がつかない場合、むしろ普通のOSとしての挙動になるだろう。 不明:  Windowsみたいにおかしくなったらリブート、というのと違い、組み込みは1年稼動し っ放しというのもざらなので、先ほどの意見は全く正しいと思う。最大何個確保するの か調べるべき。JAVAではメモリの確保と解放が把握できないというのなら、JAVAは向い てないということかもしれない。 不明:  私もC++を使っていて、ヒープには気を使う。(書名、聞き損ね)という本に検証例 が載っている。印象的だったのはヒープの割付を16の倍数に拡大してしまうことでフ ラグメントを防ぐというやり方。もったいなくはあるが、メリットも大きい。クヌース の本は一読を薦める。JAVAで使えるか分からないが、昔MACでやっていた二重ポインタと (聞き損ね)は使える方法なので、できるかどうか調べてみては。 大山:  組み込みでヒープをバンバン使うと言う人は。(数え上げて)……わりと少数派のよ う。使っていて問題はあるのか。 不明:  好きではないが、旧いライブラリの互換性を確保するために仕方なくいやいや使って いると言うのが正直なところ。ドキュメントを見てもほとんどおまじないの類で、不確 定な部分は多い。これまで動いていたと言う実績もある。 不明:  私の場合使ってはいるが、昔からの手法で、ベースとなるアプリケーションの部分。 どんなデータがくるかわからないような場合、ヒープを使うことに利がある。簡単に使 えるけど、使い方を間違えた場合の不具合が分かり辛いという弱点はある。そうした簡 単さと不具合がトレードオフとなっている。 不明:  ヒープを使うなとかMallocを使うなとか、単純にそういうものでもないかも。組み込 みの場合、中で何が起こっているかは全部とまではいわないが出来るだけ確認したい。 中身を確認するためのミドルウェアもたくさん出ているし、確認出来ればいい。 大山:  どうまとめていいか分からないが、こういうことをまとめた本がある。「省メモリの デザインパターン」という本。こういう問題を知らないで手を出すと痛い目にあう。あ と一つ重要なパターンとして、動いていたコードに手を出すな、という事がいえるかも しれない。 不明:  さっきと逆の話で、ヒープを使うなという規則や不文律などがある方はどのくらいい るか。 (挙手で確認、8人くらい) 不明:  明文化はされていない。上司が「こういう時はそういう風にはしない」というように 教えるのでやらない。ツールを作りたい時、UnixだのWindowsだのでその場限り動けばい い、というのであれば簡単なので使う。 不明:  ヒープの問題で言えばMallocが問題と言うわけではないと思う。最初のテストで はMallocを他のに置き換えるとどのくらいゴミがたまるか試す。今回のように何が どういう順でくるかわからない時、全てのパターンを網羅することは不可能。 大山:  だいぶ時間が過ぎてしまい、パターンを挙げてもらう時間がなくなってきた。 昨日いっていたものを上げて欲しい。 森:  実装の最下層に近いパターンで開発プロセスに近いもの。JAVAなどで有名だが、 MVCの発展系でMUIモデル。ユーザインターフェースとモデルを別々に実装する。こ れ自体は既存の方法で珍しくもないが、組み込みで何故使うかと言うと、ハードウ ェアの納期は遅れるものなので、モデルだけでも事前にテストしたいということ。 Windowsのマルチタスクでモデルのテストを無理やり済ませ、ハードがあがって来た ときにユーザインタフェースをくっつけてテストする。 大山:  それはウチでもやる。実際MVCを使うようなことはまずない。ビジュアルツールを 使う場合MVCにはならない。挙げてなかったが、言われてみれば重要なパターンだと 思う。最近はUIの方がパソコンのシミュレートで済んで、NCの方が実機がいるような 感じだがどうか。 森:  レイヤの見方による。NCの部分にデバイスドライバがあるような感じ。どちらにし ても難しい。 (話題が変わって、残り時間がもうない状況) 大山:  3分で、どういうパターンでどんな御利益があるのかまとめて欲しい。 二上:  ししおどしは究極のパターン。  データフローモデルで要求を適切に表現できる時、どんな本にもアプリケーション に着目と書いてあるが、(聞き落とし)。  次のシートにいくと、今の要求モデルを残したまま、ターミネータとプロセスの間 にIOなどが入ってくる。下に入れるのでなく、つまり多層化しないで水平に展開する。 人間2.5次元は理解しづらいので、2次元を保つようにする。  (古典的な割り込みの話)  ししおどしのような、リソース制限がきつくないものならわりと簡単。  これがパターンと言うか定石。 大山:  このパターンは応用が利くのか。 二上:  この種の小規模で割り込みとか同期制御とかが自由に使えるような環境であれば、 これだけで万事OK。時間的に競ってる、プロセッサのループ中に外部情報が変わっ てしまうような場合だと無理。 大山:  パターン化できると勉強が楽になると思うが。 二上:  構造化では無理というか、諦めた。教科書になっているか、という意味なら、 sessameはそこまで進んでない。 大山:  1つのパターンにしても、各人でずい分やり方が異なるものであるようだ。たくさん パターンを出してもらいたかったが、一つ一つに踏み込んでいたら時間がなくなってしまった。 服部:  デザインパターンは引き続き募集中なので、何かあればメーリングリストに出して欲しい。 (挨拶して終了)