てくすた

ピクスタ株式会社のエンジニア・デザイナーがつづるよもやまテクニカルブログです

RubyKaigi 2018 2日目まとめ

こんにちは!ピクスタ開発部です。

f:id:Yasaichi:20180601173356j:plain

RubyKaigi 1日目に引き続き、2日目も実況ツイートをしました!
それでは、2日目の開発部のメンバーが選りすぐりのセッションを紹介します。

mruby can be more lightweight

概要

最近のマイコンはCPUとメモリの容量が大きくなってきているため、mrubyをそのまま落として使用しても十分使えるだろうと思ったけど、そうでもなかったので、小さくするぞ!\\\٩( 'ω' )و //// という発表でした。

結論とアプローチの方法

結論から言うと、距離センサーを起動した直後のRAMの使用サイズがdefaultだと152,829 Byteだったものが、66,919 Byteに圧縮することができたようです。

メモリ使用量を圧縮するためのアプローチとして、実行時に既に定義されているメソッドをROMに格納し、RAMに格納されているものは動的に処理されるメソッドだけにして、メモリ使用量を抑えるというものでした。

また、HashとArrayのメモリ領域の確保の方法を比較した結果、Hashは空ではない場合の最小のメモリ割り当てが192Byteなのに対して、Arrayは4Byteとなるため、メモリ領域を効率的に使用する方法の紹介や、Rubyのしくみでも言及されていた処理についても話されていたので、Rubyの仕組みを知っていているとmrubyにも活かせるのだと思いました。

mrubyは実行時の全体のメモリ割り当ては最も大きなメモリ領域(RClass)に引っ張られます。今回の修正はRClassにROMの参照ポインタを追加したため、RClassのメモリ確保領域が増えてしまう問題がありました。今後は、iv*1を分離し、RClass自体のメモリ領域を増やさないようにし、マージに向けて修正するとのことでした。

RubyではRAMにデータを格納して処理をしており、mrubyもそれを踏襲しているのですが、「データをRAMに格納する」という前提を疑い、処理(メソッド)を見て適切なところに配置し直すという改善をしていたので、アプローチそのものが素晴らしいと思いました。

Guild Prototype

YARVの開発やGCの性能改善など、Rubyの高速化に携わってきた笹田耕一さんによるGuildに関するセッションでした。

GuildはRuby 3に向けて現在開発が進められている並行計算モデルで、2016年のRubyKaigiにおいて提案されました。
現在のCRubyでは、GVL (Giant/Global VM Lock) と呼ばれる機構によってある瞬間に実行されるスレッドの数は一つに制限されているため*2、マルチコアのマシンにおいてはその性能を十分に活かすことができません。Guildでは、Guildという単位ごとにプログラムの並列実行を許可することでこの問題に対処しています。また、Rubyの高い生産性を維持するために、排他制御などのデータの同期についてプログラマが考えなくて済むようにする、ということにもチャレンジしています。

セッションでは、現時点でのプロトタイプを使ったデモが披露された後、現時点での仕様と実装についての話がありました。

デモのひとつに「フィボナッチ数を40個のvCPUが割り当てられた仮想マシンで10万回計算する」というものがありました。
個人的に印象的だったのが、この計算をGuildを用いて並列化した際のパフォーマンスです。Guildの数を増やしていくとそれに比例して高速化され、40個になるとそれ以上速くならないという結果から、現在のCRubyのThreadでは不可能なマルチコアの利用が実現できていることがわかり、感動しました。

また、仕様と実装のパートは2年前のセッションよりも踏み込んだ内容になっていました。具体的には、Guild間で共有可能なオブジェクトの詳細や、これらのオブジェクトを受け渡すためのAPI、およびGuildとThread/Fiberとの関係とGCのタイミングについて話されていました。
2年前のセッションでは、Guild間でのオブジェクトの受け渡しにはChannelを使っていたので、筆者は「GuildはCSPモデルの派生である」と捉えていました。しかしながら、今回のセッションではsend/receiveを使ったActorモデルになっており、この変更の背景には何があったのだろうか、というのが少し気になりました*3

全体的に、Rubyでのよりよい並行プログラミングの実現に向けてGuildが前進している現状がわかる、個人的に大満足のセッションでした。

Firmware programming with mruby/c

マイコン用のファームウェアを書く新しい選択肢としてmruby/cがあり、醸造業向けIoTのプロジェクトでmruby/cを採用したという発表でした。

mruby/cとは

mruby/cはRubyを使うことでC言語に比べて実装の効率化を上げれたり、省メモリで動作できることにより、低消費電力で稼働できるとのことです。 mrubyとmruby/cの違いですが、mrubyは機能や実行速度を重要視していますが、mruby/cでは省メモリや起動速度を重要視しています。もう一つの違いとして、mrubyはRTOS(Real-time OS)等のOSを使って動かすことが一般的ですが、mruby/cはOSなしで動作します。

醸造業向けIoTのプロジェクト

酒造現場では麹(こうじ)や醪(もろみ)などの品温変化をこまめに監視する必要があるそうです。毎回現場に出向き確認するというのは負担なので、環境温度・湿度等をインターネット経由でサーバーに保管して、スマホ等で確認できるようにしたようです。

mruby/cを採用した理由

プロトタイピングではRaspberry Pi などのシングルボードコンピュータを使うのが一般的ですが、セキュリティ面や低消費電力性を考慮して、マイコンを採用することとしました。そこでなぜRubyだったのかということろは触れられていなかったと思うのですが、以下のサイトで説明されている内容が理由なのかなと思います。

Rubyを使ったWebアプリ開発を得意としている一方で、センサーなどのハードウェア制御プログラム開発の知見がなかったため、Rubyと仕様が似ていてハードウェア制御に向いたプログラミング言語「mruby/c」に着目しました

老舗酒造にて温度変化を測定するIoTシステムを導入開始 | しまねソフト研究開発センター

どのように開発を進めるか

開発環境については、PSoC CreatorというIDEを使用していくようです。(ただしWindowsでのみ使える)デバックについては、現状はステップ実行ができないのでprintデバッグを使います。ただし、コードがそこまで複雑にならないのでprintデバックで十分とのことでした。 文法的に使えるものがまだ十分ではなく、今後Array#each, Hash#each, Hash#to_jsonを使えるようになるそうです。Hash#to_jsonはAPIリクエスト等で使う場面がでてくるので待ち遠しいとのことでした。

mruby/cに貢献するには?

対応しているボードが少ないので、ハードウェアに近い部分を抽象化するHAL(Hardware Abstract Layer)を実装することでボードを増やすことができるそうです。また、ドキュメントも少なかったりするので書いてほしいとのことでした。

私は学生のころ組込みシステム系の授業でマイコンを使用したことがあり、そのころはC言語でプログラミングをしていました。最近はArduinoやmbed等でC++ライクな言語を使うことができますが、Rubyを使用できるとコードの冗長的なところを減らせたり、既存ライブラリを使用できるとWebとの親和性が高くなって、IoTと仲良くなれそうですね。

Improve Ruby coding style rules and Lint

speakerdeck.com

RuboCopのコミッタの@koicさんによるセッションでした。 (Rubocopに関する昨日のセッションに関するまとめがこちらに載っています。併せてお読みください。)

1. styleとlintの違いはなにか

styleは文化と密接な関係があります。 有名なコーディングスタイルとしてはShugo MaedaさんのRubyコーディング規約やMinero AokiさんRuby のコーディングスタイルなどがあります。 またRubocopは基本的にRubyStyleGuidに基づいてスタイルを規定しています。 社内でコーディング規約が決まっている場合もあります。 このようにコーディングスタイルとは文化によって異なるものであり、必要に応じて柔軟にカスタマイズされ得るものです。

一方lintはstyleとは違い環境の違いとは関係なく守るべきものと言えます。 例えばバグの元となり得る記述や、予想される将来のインタフェース変更を考慮できていない記述は指摘の対象になります。 具体的な例として、Ruby2.6からERB.newの引数はキーワード引数を受け付けるように変更されるので、それに伴いRubocopで警告が出るようになった、というものが挙げられました。

2. 新たなRubocopのルールがプロジェクトから生まれる話

あるチームのプロジェクトで指摘された事象は、別のプロジェクトでも指摘される可能性があります。 なので自分のプロジェクトでRubocopに導入できるようなルールがあったら積極的にRubocopにPRを送ってOSS活動するのが良い、という話でした。 あるプロジェクトで指摘された内容がRubocopに取り込まれた例として、トップレベルでのincludeに警告を出すというPRが取り上げられていました。それに伴いRubocopでルールを作成する具体的な方法についても説明がありました。

3. OSSコミュニティが横断的に影響を与え合う話

Railsのコミッタにより、Railsのcustom copを切り出してRubocopに移してはどうかという提案がありました。 その後その提案どおりにRubocopに移したところ、それまではRubocopコミュニティには現れなかったようなRailsコミュニティの人々がRubocopコミュニティで発言をしてくれるようになったということでした。 このような「社会現象」が起きたというのはとても興味深い出来事だったとのことでした。

このセッションを聞いていて最も印象に残った言葉があります。 それは、「僕のいないところで僕がレビューをするんですよ。これってすごいですよね」というものでした。 これぞまさにエンジニアだな、という気持ちになりましたし、OSSというものの価値を強く感じました。

おわりに

3日目も実況ツイートしていきます!よければフォローもお願いします!

twitter.com

* * * * *

ピクスタではエンジニアを募集しています!

recruit.pixta.co.jp

*1:Instance variable tableの略

*2:厳密には、スレッドがI/O待ちになった際にはGVLは開放されます

*3:セッションを聞いている際にはスライドの”Actor model”という文字を見逃しており、後から判明しました