ChucKの軽量スレッド

Chuck論文を斜め読みした。ホームページトップにもあるようにChucKはリアルタイム音声合成/作曲/パフォーマンスを目的としたシステムで、強力に正確な時間(strongly-timed)なこともウリにしている。論文ではその時間管理の部分と軽量スレッドの関係についても触れられていた。

ChucKで音を出すには、D/A Converter(dac)へ何らかのオシレーターを接続し、必要ならオシレーターの設定をした後、音をならしたい時間を指定する。最後の音をならす時間指定の前までがChucKでの軽量スレッドの実行単位(Shredと呼ばれている)となり、鳴らす音の時間指定した時点で音声エンジンによって音声処理され、Shred切り替え処理(Shredulerと呼ばれる)でキューにいるShredが処理される。以下は単一Shred時のフロー(論文だとp.77, fig.3.34)

複数Shredを並列実行する場合はsporkにShredとして実行する関数を渡す。OSCやMIDI等の外部信号イベントへの反応のためのハンドラ登録もsporkで行う。この辺りはjavascriptなんかでイベントハンドラ登録するのと同じ。sporkは先割れスプーン(spoon + fork)のことなのでfork意識してるはず。

以下は時間指定の部分だけ抜き出したコード例。

100::ms => now

'=>'は代入演算子みたいなもので、上記はコード実行時から100ms経過するまで待機、という意味になる。ソースは見てないけど上記のようなnowへの代入が実行された時点でshredulerに制御を返して他のshred処理をしてる、というような記述が論文中にあった。nowへのduration代入でなくme.yield();すると時間をまたずにその場でshredulerに処理を返せる。この書き方だと軽量スレッドをサポートする一般的なプログラミング言語の実行単位切り替えに似ている。

ChucKで軽量スレッドを採用する主なメリットは、OSのスレッド機構でなくユーザ空間の協調スレッドを使うことでコードを書く人の意図したタイミングでShredを制御できること、と書いてあってこれについては時間軸を持つメディアを扱うものらしいと感じた。あとは普通のthreadだとdead lock気にするの嫌とかスケジューラがユーザ空間で動いてるからカーネルに手を入れずに最適化できるとか書いてあってこれらは普通のプログラミングと変わらない。

論文中では他にもコンピュータを使った作曲システムの歴史とかリアルタイムにコード変更反映するためのVM周りの話とかパフォーマンスと関係するon the fly programmingの話とかあって面白そうな感じでした。