週刊nmosh - IDEビルドの改善 / DSP言語 / CProcedureへの再入

全然週刊じゃない...
nmoshとmoshの乖離がけっこう大きくなってきてどうするか舵取りが難しい。個人的にはもうnmoshしか使っていないので、今後もpsyntaxやautotools + libtoolのコードベースを維持できるかにあまり自信が無いところ。
もっとも、autotoolsは未だに対応する価値のあるレガシーに分類されるので扱いが難しい。CMakeは特に日本語圏でマイナーで、殆どのLinuxユーザはCMakeの使い方を知らない。ただ、autotoolsにちゃんと対応したScheme処理系もあまり多くないので微妙なところではある。(GuileとかGaucheが有るけど)
実行ファイル名をmoshにしておくと営業的に不利というのもある(Mobile shellの方と被っているため)。殆どのパッケージングシステムでは実行ファイル名が重複する場合の考察が無いので、moshという名前のままにしておくとMacPortsとかFedoraのような営業戦略的に重要なシステムに収録してもらえない。

IDEビルドの改善

IDEビルド(Visual StudioXCode上のビルド)で、直接nmoshアプレット(= ただのR6RSライブラリ)を起動できるようにした。CMake変数NMOSH_CHECKMOSH_APPLETSに列挙したアプレットのそれぞれを自動実行する.exeを自動的に生成する。
(Schemeって書いてあるのはXcodeの機能であって別にScheme言語をサポートしているわけでない)
これで、IDE上で"実行"ボタンを押すだけで即実行できる。手元のプロジェクトでは、さらにスクリプトバイトコードコンパイルも統合している。なんだかんだいってVisual StudioXcodeのネイティブコードデバッガはそれなりに優秀なので、ネイティブコード側のデバッグに使えるのは便利。
(CMakeのような方法でIDEのプロジェクトファイルを生成させると、デバッグ設定等が忘れられてしまう。このため、生成直後のプロジェクトファイルがそれなりに使い物になることが重要になる。)
まだ、AndroidMacOSのネイティブアプリのようなDeployプロセスが必要なプロジェクトには対応していない。

DSP言語

頂点処理や音声処理のためのDSP言語を系統化してマルチバックエンドにしようと考えている。現状は重い処理はC言語で手書きしてnmoshはデータ構造のパースや後処理というのが通常の書かれ方だけど、マルチデバイス対応を考えるとこれは面倒なので。
言語仕様はアセンブラ風で、ORCのものを借りてくる( http://code.entropywave.com/documentation/orc/orc-opcodes.html )。ORCがこの手のシステムでもっとも低機能だと考えられるのと、最初からHLSLやOpenCLに特化してしまうと実行できるデバイスが限られてしまうため。

  • 分岐は無し
  • プログラムには等長の1次元配列をN個入力として与え、M個の同じ長さの出力を得る(= 拡大縮小には使えない)
  • いくつかの仮想の配列を設ける(sin/cos等の関数や、単調増加するindex等)。
    • ORCのようにライブラリ的な機能制約が有るケースや、TegraのようにALU boundになりやすいアーキテクチャでは実際の配列を生成して与える。
  • 実行は非同期で、入出力する配列の依存関係で同期する。

将来的にはもっとGenericなアプリケーションを書けるものにしたいが、OpenGL ES 2.0なデバイスがmajorityのうちはこのレベルを越えるのは難しい気がする。
OpenGL ES 2.0はcore機能に任意の描画操作の完了を待つ機能が無い(投入したコマンドの全完了を待つか、拡張を使うことになる)。ES 3.0からは導入されているが、まだまだ対応デバイスが普及するまでには時間が掛かりそう。
OpenCLは最初から細粒度な同期をサポートしている。ただし、クライアントプログラムから任意のタイミングでイベントを発火できるのは1.1以降なので、1.0はサポートしない。nmoshの非同期フレームワークは最初から(任意の数のイベントオブジェクトを任意のタイミングで発火できる)OpenCL 1.1を前提にデザインされている。
RenderScriptは期待ほど早くないので対応は保留。Android 4.2からそれなりに改善されたように見えるが、どちらかというとOpenCLの方に対応して欲しい。。(たぶんiOSがサポートするまで良い動きは無いだろう)

CProcedureへの再入

nmoshは伝統的にCProcedureへの再入を許していない。つまり、VMからネイティブコードを呼びだしたとき、VM再帰してさらに自分自身を呼びだす というシナリオをサポートしていない。
これは、ネイティブコード手続きを表すCProcedureオブジェクトにreturnのためのVMコードを埋め込んでいるためで、基本的に呼び出し中にVMに戻る可能性のある手続き全てで問題になる( https://code.google.com/p/mosh-scheme/issues/detail?id=198 )。
今回は、returnコードをヒープ上に移すことで再入を可能にしたが、世間的には、単なるCProcedure呼び出しでヒープ確保が行われるのは望ましくないので難しい。Cスタック側に置けない理由は何だろうか。