***********************************************
セッションS1-d 分科会
テーマ :mruby/cによるマルチプログラミングの概要
講師 :田中 和明(九州工業大学)
日時 :2018/08/30 21:00 - 22:30
参加人数:約35名
************************************************
■概要
・マルチプログラミング
・mrubyとmruby/c
複数のプログラムを走らせたい
⇒普通はOSの仕事であるが、OSなしでやりたい!
(OSはリッチな環境が必要で、OSのフル機能は必要ないような場面)
■自己紹介
・田中和明(九州工業大学 情報工学部)
・教育-情報基礎、プログラミング、データ構造とアルゴリズムなどを教えている。
(ほとんどC言語)
・研究-・組込みシステム(mruby、全体の7割)
・ブロックチェーン技術(をIoTで利用する)
・LPWA、光学測量に関する共同研究
・mruby:2010年に経済産業省にお金をもらって開発した
オープンソースになったが、使い方が分からなかったり、そもそもツールも少
なくあまり使ってもらえなかった。
⇒ お金をもらって、ツールを増やして、小型化にfocusし、ここ半年で
ようやく普及してきた。
もうすでに、製品に使われている。(数として、一番多いのはPS4のゲームソフトでの利用)
ハードウェアではなく、システムやソフトウェアやゲームへの組込みに
使われて始めた。
この現状でサポートできないエリア、特にIoTで重要な領域を狙ったのが、
mruby/cにプロジェクトになる。基本的にはmrubyと一緒。
VMに工夫がしてあり、非常に小型化できたり、
マルチプログラミングできたりする。
・マルチプログラミングとは:
複数の機能を実装するとプログラムが複雑化する
-異なるタイミングでそれぞれの機能を動かす
-機能ごとに実装を分離
-セキュリティ
-保守性
シングルでやろうとタイミングを気にする必要や、お互いを考える必要や、
OSの必要性がでてきて大規模になる可能性がある
例:赤色LEDを1秒間隔で点滅させる(mrubyプログラム)
while true do
output 0,1
sleep_ms 1000
output 0,0
sleep_ms 1000
end
output : GPIO出力
sleep_ms : スリープ
問題
:赤色LEDを1秒間隔で点滅させる
:緑色LEDを0.1秒間隔で点滅させる
・シングルプログラミングの場合
t = 0
while true do
# 緑色LED
if t%2 == 0 then
output 7, 0
else
output 7, 1
end
# 赤色LED&リセット
if t == 10 then
output 0, 1
elsif t >= 20 then
t = 0
output 0, 0
end
sleep_ms 100
t += 1
end
これは可能だが、考えるのが大変
↓
・マルチプログラミングを実現するための技術
・割込み
・スレッド
・マルチタスク(プロセス)
これらの技術を使いつつ、簡単に実装したい→mruby/cのマルチプログラミング
while true do while true do
output 7, 1 output 7, 1
sleep_ms 100 sleep_ms 100
output 7, 0 output 7, 0
sleep_ms 100 sleep_ms 100
end end
mruby/cのマルチプログラミングでは、
VMが二つのプログラムを切り替えながら実行している
これが本日の話題
<質疑応答>
質問:
・平行して動いているが、始まるタイミングはそこまで気にしてない?
回答:
・二つのプログラムがそれっぽく同時に動いている感じ
実際には少しずつ実行を切り替えている。現実的にはタイミングの問題や排他制御が必要。
今回は、各LED(GPIO)のアクセスは独立しているので、排他制御は不要
・mruby
-Rubyを軽量化したもの
~Rubyにほぼ準拠しており、Rubyの開発効率を組込みソフト開発へ活かす
-Rubyとの互換性を重視
~Ruby技術者が組込み開発できる
-消費メモリは400KB程度
割と実績がある。
mrubyの利用事例:ネットラークル−タ(IIJ社)
ゲーム(スクエアエニックス、SidMeier's)
Apacheモジュール(OSS)
ETロボコン(アフレル社、ほか)
GUIライブラリ(ILC社)
<質疑応答>
質問:
・なんでmrubyは利用されたのか?
回答:
・modmruby:Rubyでやりたかったがでかいので、軽いmrubyが導入された
・ルータ:軽いmrubyがオープンソース化されて採用された。ルータの設定などで使う
・ゲーム:業界がスプリクト言語をほしがってた。
外注との言語を切り分けたいため(影響範囲を限定したい)。
・mruby/c
-mrubyをさらに軽量化したもの ~40KB程度
ワンチップマイコンでの動作を想定したもののため、資源が限られる
(実際には20KBぐらいで動く、あとはプログラムが消費するメモリに依存する)
(最小、例えば hello world であれば、10KB程度でも動く)
-Rubyとの互換性というよりもrubyっぽいものを考えており、
小型化を重視している。
-最小限のクラスライブラリしか実装されてないため、サポートされてない
Rubyの機能は多数ある
-OSを必要としない
<質疑応答>
質問:
・実装するかどうかの判断の基準は?
回答:
・基準は特にない。依頼があれば検討して実装するか判断する。
個人に依存する。
質問:
・コンパイラによる最適化は難しい?
回答:
・mrubyとmruby/cのコンパイラは同じで、まつもとさんに聞いてほしい。
rubyがソースコードをそのままインタプリターのかけて実行するのに対し、
mrubyとmruby/cはソースコードをコンパイルし、mrubyバイトコードとし、
それぞれのVMで実行させる。これによりメモリを抑えることができる。
mruby VMとmruby/c VMは動きは一緒、サポートされるクラスやメソッドなどが違う
■mruby/cのポイント
・OSを必要としない
・OSが提供する機能を持つ
-マルチプログラミング
複数プログラムのコンカレント実行
-メモリ管理
-排他制御
・ユーザプログラムとして実行する(特権命令は必要ない)
・mrubyのバイトコード
→ソースコードのコンパイルにより生成される。
アセンブリに近い言語
各レジスタはオブジェクトのインスタンスが入る
SEND(C言語の関数呼び出し):メッセージパッシングを行う
このコードは機種に依存しないのでどのデバイスでも動く。
・mruby VM
VMがバイトコードを実行する。
VMを作ればどこでも実行することができる。
mruby/c VMのアイデア
・複数のプログラム(複数のバイトコード)を実行する。
loop do
for i=1 to N do
current_program = program[i]
instruction = Fetch(current_program)
Execute(instruction)
end
end
1命令ごとに実行プログラムをスイッチ。可能だがオーバヘッドが大きくなるのでやらない。
実行効率の問題
・実行効率が悪いので、
いくつかのバイトコードを実行する。
loop do
for i=1 to N do
current_program = program[i]
for j=1 to M do
instruction = Fetch(current_program)
Execute(instruction)
end
end
end
パフォーマンスは上がる
問題:実行の公平性が保証されない(命令ごとに実行時間が異なるから)
・実行の公平性
・プログラム間で実行時間が公平ではない。
時間が来たら切り替える→ある程度の公平性は保たれる
loop do
for i=1 to N do
current_program = program[i]
start_time = GetCurrentTime()
while GetCurrentTime() < (start_time + TIME_SLICE) do
instruction = Fetch(current_program)
Execute(instruction)
end
end
end
しかし、これは重い(時刻の取得が重い!)。あくまで仮想的なプログラム。
そのため、、
・mruby/cの実装では、
・タイマー割込みが使える場合は、
割込みでプログラムを切り替える。
割り込み発生時に、実行中のプログラムの flag に1を入れる
⇒次の命令を実行する前にフラグをチェックする
⇒切り替わる
この処理は軽い
Result
・Execution time
-Calculate 32th Fibonacci number using recursion
複数のフィボナッチ数計算をコンカレントに実行している
割込みだと単体(フルパフォーマンス)と同じような結果が得られた。
・サンプルプログラムの紹介
スイッチが押されると状態が変化する
0⇒1⇒0⇒1→0→1
スイッチが押されてから500msは入力を無視する
状態に応じてLEDの点滅をする
シングルプログラムで考えると難しい。
→ 2つのプログラムにすると簡単
(1) スイッチが押されたら、状態を変化させる(同時に500msの入力禁止=プログラムのスリープ)
(2) 状態に応じてLEDを点滅させる
状態0:50msの点滅
状態1:500msの点滅
状態2:1sの点滅
<質疑応答>
質問:
・状態が変わったとき、点滅の途中はどうするか?
回答:
・排他制御とかを入れるとか、、、
⇒ コメント:使いにくそう、、、
・global変数によってプログラム間の通信ができる。
アトミックにできるため排他制御は必要ない。
これが現状のmruby/c
質問:
・優先度があればどう動くかがわかるのでは?
少しコードを入れると、優先度スケジューリングできそう
回答:
・2個以上の場合、優先度がないとどうなるかわからなそう、、、
シンプルさはどこまで保たれるのか
⇒rubyを使うぐらいには保たれる
VMに負担があるいくだけだから
指摘:ドキュメントがない
■まとめ
なし