週刊mosh - どころじゃない

おかげさまでひとつの本番を無事終えました。。nmoshは2時間元気に作動してちゃんと照明制御ができた(らしい)。
まだまだnmoshはイベントが目白押し状態だけど、来月には通常営業に戻せるはず。。GCのアップデートとかはその後ということでひとつ。。

リアルタイムアプリケーション の2

結局、リアルタイムアプリケーションをちゃんと動かすには、今のところ外部にシーケンサをおいてリアルタイム性の必要な処理はそちらに任せるしかなさそう というのが今回の結論。
nmoshはコンパイル後のVMバイトコードがかなり大きい。VMバイトコードはヒープオブジェクトなので、nmosh実行中のmoshは非常に巨大なヒープを抱えることになる。そういう状況ではBoehmGCのポーズ時間が100msとかになってしまうので、世代別コレクタが使えないのが地味に効いてくる。。(一応、BoehmGCにはincrementalコレクタが有るが、Windows上だとかなり遅くなってしまう。)

反省会

(あとでちゃんと書く)

  • GC時間に上界が絶対必要。BoehmGCにも一応インターフェースは有るが(1ページ収集するごとにコールバックするモード)、試す時間が取れなかった
    • あと良いAPIが思いつかなかった
  • 多少のヒープ削減努力をしたところで、nmoshやnmoshでexpandされたライブラリ自体が巨大なのであまり効果がなかった。
  • expandされたライブラリが巨大なのは何もかもをlambdaに展開しているのが大きい。ネイティブのletはmoshVMコンパイラのバグを踏みやすいのでnmoshでは使えていない。
  • あと、nmoshのsyntax-caseはmoshの(match)のように、マッチ節をすべてif-then-elseに展開してしまう。psyntax-moshのように、マッチ節は毎回インタプリトする構造にしたほうが、出力するコードサイズは削減できる。
    • というかmatchは超頻出なのでGaucheのようなちゃんとした実装を準備すべきかもしれない
  • 今回nmoshを採用したのは単にWindows上でDLLをFFIできて、CMakeでビルド出来、S式のような可読データ構造のread/writeが単体でできる処理系が他に無かったから。
    • しかし、GMP(MPFR)が無いとビルドできないのは非常にキツい
    • Schemeコード自体は本当にグルーとしか言えないような量しか今回書いていない(S式をreadしてbytevectorにし、"適宜"シーケンサDLLに渡すだけ)
  • 非同期構文は大活躍。もともと(yuni async)はこのためにデザインした。
  • Queueをひとつしか持てないデザインは困る。
    • 今回、glibのイベントループと非同期APIのイベントループが混ぜられない問題が起きた。
    • glibのイベントループをシーケンサに追い出してScheme側からは触らないデザインにして回避したが。。
  • Queueの拡張は多分必要
    • 別スレッドへのenqueue
    • glibとかGCDのようなほかのイベントループインターフェースを混ぜる
    • queueのidleコールバック