2013年4月27日土曜日

Linux Mint 14 + Raring / Emscripten : hello_world.cxx --> hello_world.js


環境の準備:
  1. Linux Mint 14 + Raring 状態で apt-get するなどして clangllvm を導入
    (※もちろん必要ならソースからビルドして導入しても構わない)
  2. apt-get するなどして nodejs を導入
    (※V8や他のJS処理系でも構わないようだが: 後述の ~/.emscripten 参照)
  3. emscripten を github から git clone するなどしてお好みの場所へ配置し、 `em++`を実行し、"~/.emscripten"を生成
    (※著者環境では ~/opt/emscripten へ git clone し、パスを通してある ~/opt/binに ln -s ../emscripten/em++ して em++ を任意の場所で実行可能にしています)
"Hello, world": 
  1. ふつーにC++でソース書く
  2. ふつーに翻訳する。 // やや時間がかかる。結果をよく見ると納得。
    `em++ hello_world.cxx -o hello_world.js`
  3. ふつーに実行する。 // 感動する。
    `nodejs hello_world.js`
最も簡単なソースと結果:
.html出力:

出力ファイル名を.htmlにすると、HTML5でローディングインジケーター付きのcanvasエリアとコンソールを用意したHTMLファイルを生成してくれる。

`em++ hello_world.cxx -o hello_world.html`

もちろん出力された"hello_world.html"はウェブブラウザーで動作する。



--preload-fileとファイルシステム:

`std::ifstream i("hoge.txt");`して扱える。但しstd::ofstreamは翻訳上は問題無いけれど、実行時には無かった事になる。

実行時にサーバーにファイルを読みに行くのではなく、翻訳時に` -o hoge.html --preload-file input1.txt --preload-file input2.txt`の様にしておくと、hoge.dataを生成し、実行時にはどうやらこれを一度だけ読みに来る。hoge.dataには--preload-fileオプションで渡したファイルが全て単純に結合されて格納される。

なので、翻訳後に変化するファイルはこの方法では扱えないか、トリッキーな実装が必要になりそう。

最適化:

-O1、-O2が有効。

最適化フラグを付けないと"Hello, world"すら122,819行、351,259単語、3,414,649バイトものJavaScriptとしてはとんでもなくバケモノサイズなhello_world.jsが得られる。

これがO1で68,896行、263,921単語、1,725,088バイトに縮む。O2では4,913行、22,536単語、786,438バイトにまで縮む。

これはもちろん最終的な.jsのファイルサイズが小さくなるのは副次的な効果で、実行速度ももちろん向上する。

加えて、`-s ASM_JS=1`を翻訳時にオプションとして加えると、"asm.js"を使う様に翻訳されるらしい。但しこれは現在のところasm.jsをサポートした特別なFirefoxのブランチでしか試せない。試せないのだけど、通常のウェブブラウザーが現状実装するJavaScript処理系に比べると驚異的な性能を発揮するベンチマークが得られている。

おまけ、ベンチマーク:

emscriptenの中には~/.emscriptenで指定するJavaScript処理系とネイティブでのベンチマークが備わっている。

`python tests/runner.py benchmark`

言うまでも無くJavaScriptはネイティブと比べれば遥かに遅いのだけど、なかなか頑張ってはいる、そんなスコアが見れる。Phenom2-940、nodejs-0.6.19環境では実行時間にして凡そ3〜5倍程度遅い結果が見えた。

所感:

まさか何事も無く本当に、いくら簡単な"Hello, world"とは言え、正真正銘のC++のソースコードをLLVMを経由してJavaScriptにできてしまった事の驚き感動は隠せない。

これまで研究開発をC++で行うと、特にGLも使っていたりするとそのプロダクトのリアルタイムでのデモンストレーションを一般的なプレゼンテーションに組み込んで行うのはやや難しい事でしたし、いくらJavaScriptのライブラリーが充実したところで所詮は現行のウェブブラウザーの搭載するJavaScriptではゲームを含めアプリ開発とかあまり積極的にソースコードを書きたいと思えるものではありませんでした。それにNative-ClientにもChromium系でしか動作しない事やそもそも何時まで経ってもGCC-4.3ベースのレガシー環境が標準だったりと、いくらC++が使えるとは言え残念感でいっぱいでした…。emscriptenならば、C++11を先日完全実装したclang(但し3.2リリース版ではまだです)を使い、ウェブブラウザーサイドという実行環境を殆ど考える必要も無く、それでいてウェブアプリを開発できるのです…。ウェブブラウザーがJavaScriptしか現実的に実装しない事には大変不満が爆発するところではありますが、割とそんなことどうでもよくC++で仕事ができるのです…(´;ω;`)ブワッ

さらにこのEmscripten、どうやらSDLとOpenGLをCanvasとWebGLにもしてくれるらしい。GPU最先端の研究開発ではGL-4.3動かないとやだーとか言ってるけど、最低限の表現としてはまあGLES-2.0が動くなら実用はできます。

正直、Emscriptenについてはまだそれほど実用性が無いプロジェクトなのだろうと思い込んでろくに確かめもせずに居ましたが、大きな間違いでした。これからもっと遊んでみようと思います( ・`ω・´)

参考:


0 件のコメント:

コメントを投稿