RTOS は monami-ya.mrb を遅くするか?

とある,案件契約ではない非公式なやりとりから. 個人が特定されるような内容ではないので,これくらいなら許され…ますよね.

mruby 自身もC言語に比べて処理に時間がかかるところに,RTOSが入るとさらに遅くなったりしないのか少し心配です.

個人が特定されるどころか,同じような直感を持たれる方,案外多いのではないかなと思います. 機器組み込み業界で働いておられるエンジニアの中にもいらっしゃるのではないかな,とも.

端的に言うと,RTOS が入ると遅くなるというのは,概ね誤解です. いやもちろん RTOS がゼロオーバヘッドだと言っているわけではありません.

いまや会社の製品の機能として提供されている部分なので,本来なら会社の公式ページに書くべきところですが,そうすると定量計測してホワイトペーパーにしないと格好がつきません. そこまで喫緊の話でもない(非公式なやりとりですし)ので,こちらに書いておきます.

RTOS とは何か?

そもそも OS とは何か

RTOS の前に OS とは何か,から確認していきましょう. 多くのデスクトップ環境では,CPUのコア数はたかだか8個程度でしょうけれども,OS上ではより多くのCPUが存在しているかのように見えています. 本当は1つしかないメモリ空間は,MMUなどメモリ管理ハードウェアの支援を得て,プロセス毎に分けつつも,プロセス内では全メモリを専有しているように見せかけています. ストレージも,本当は1つしかなくても,ファイルシステムという構造を導入することで,複数のプロセスに競合しないように調停されます.

ざっくり言うと,OS というのは,何かを抽象化し管理し保護するソフトウェアです. 現在的なOSのほとんどは,プロセスと呼ぶ抽象化した計算機を管理し,処理がプロセスから外に漏れないようにして,物理的な計算機資源を保護しています.

RTOS は何を保護するものか

RTOS の抽象化対象は,CPUです. 実際には全ての処理は時分割されているのですが,それぞれの処理はCPUを専有しているものと(RTOSによって)勘違いさせられています. そして保護対象は,RT == Real Time が示す通り,時間です. なので,多くの RTOS は時間以外のリソースの保護については,かなり無頓着です. 最近になって,セキュリティや機能安全についての世論が固まったため,リソース保護機能付きのRTOSも増えました. それでも,リソース保護機能が時間保護を阻害するとなれば,時間保護のほうが優先されます.

ここでいう時間には,2種類あります.

ひとつは物理時間です.これは一般的な「壁時計」と同じと思って頂いて構いません. RTOS自身オーバヘッドが影響するので,重要といえば重要ではあります. しかし,CPUに与えるクロック次第で改善されやすいものでもあります.

もう一つは実行順序制約です.RTOS ではこちらのほうが重要です. RTOS では,実行順序が事前に見積もれなければならない,とされます. そして,優先されるべき処理については,他の処理を止めてでも実行して良い,とされます. 他の処理を止めれば,実行順序を見積もりやすくなりますから.

通常のOSにも実行優先度の概念はあります.しかしRTOSの場合は強烈です. アプリケーション設計者が必要と思うなら,デバイスへの割り込みすら止めることができます. CPUが持つ計算資源の全てを,特定の処理に割り当てられる. それが RTOS の特徴です.

RTOS は時間を管理する OS なので,これは当然の特徴と言えます. (計算資源 == 計算に要するクロック数 == 時間)ですから.

RTOS のオーバヘッド

RTOS は,複数の処理(タスク)に対して,それぞれが CPU が専有しているかのように見せかける抽象化を行っています. 抽象化の裏には,オーバヘッドがあります. これは,時間量として見ると,コンテキストスイッチに要する時間で表されます. 商用 RTOS の星取表で,この数値が俎上にあるのを見たことがある方も多いでしょう.

あまりにも商用 RTOS の営業さん達がけたたましく言うので,このオーバヘッドが無視できないと誤解する方が後を絶ちません. しかし実際のところ,このオーバヘッドが致命的かどうかは,アプリケーションに依ります.

mruby は,大目に見ても C言語で書くよりも2桁のオーダで遅くなります. 「週に何度も口にしない飴玉のカロリーを気にするなら,まず毎日の三食を見直しましょう」という喩えでお分かり頂けますでしょうか.

なお,RTOS のオーバヘッドとして有名な指標には,コンテキストスイッチの他に,割り込みへの応答時間もあります. こちらも,似たような議論が成り立ちます.

「RTOS は重い」神話の,ミもフタもない理由

とはいえ,「RTOS は重い」にも相応の理由は思いつきます. それは,優先度設計の難しさ,です.

既述の通り,RTOS では,高優先度の処理は,CPUへの割り込みさえも止められます. このような条件で,高優先度で実行される処理の設計が悪くCPUを専有した場合は,システムは最悪の状態になります. 低優先度の処理にはいつまでたっても,処理の機会が与えられません. (ちなみに,このような状態に陥った低優先度の処理は,RTOS 界隈の用語では,”飢餓状態”としばしば言われます.)

日本の組み込み業界では,優先度設計から詳細実装まで全てを一人でこなす例もありますが, 上流が検討もしないで適当に優先度を割り振った仕様書を元に,受託で(再受託で(再々受託で))詳細を実装するということが,しばしば行われます. こういうケースでは,組み上げてみたら真っ当に動かない,ということは,珍しくなかったりします.

それは設計の不備であり,RTOS が悪いわけではないのですが. 外から買ってきた RTOS をスケープゴートにする,ということが起こるのは,人として理解できないわけでもありません.

monami-ya.mrb は,RTOS で処理が重くなったりはしません.

…もちろん,高優先度の処理で無限ループなどされるとダメですけれども.

優先度の設定に気をつけている限りにおいて,monami-ya.mrbはRTOSと併用しても処理が重くなったりはしません. その辺りには,20年前から RTOS 関わり,TOPPERS/FI4 など RTOS の実装にも関わった経験を活かしてあります.

本家 mruby は…? メモリアロケータの部分をキチンとケアできれば,大丈夫にできると思いますよ.たぶん.