The Ruby VM: Episode III

Matzにっき から The Ruby VM: Episode III へ。体調激悪なので翻訳は未だ... 誰かやってくれたらリンクで済むのに ^^;)。

新しい VM の重要な変更点ですから、スレッドについても少し話していただきましょうか。まず Ruby 1.8 で採用されている旧スレッドモデル、そして Ruby 1.9 で採用された新しいスレッドモデルについて説明していただけますか?

まつもと さん(以下 Matz):

旧スレッドモデルはグリーンスレッドであり、Ruby が動作する全てのプラットフォームに普遍的なスレッドを提供します。私が Ruby の開発を始めた 14年前には妥当な決定だったと思います。時が過ぎ、状況も変わりました。現在、pthread などのスレッドライブラリが大半のプラットフォームで利用可能になっています。古いプラットフォームでさえ、pth ライブラリ(setjmp などを使用した pthread API を実装したスレッドライブラリ)でグリーンスレッド実装を利用することができます。

ささだ さんは YARV でネイティブスレッドを使うことを決めました。私が唯一後悔しているのは、内部構造の問題で我々のグリーンスレッドでは継続がサポートできていないことです。以前、ささださんは私に YARV では継続の実装が不可能ではない、と話しましたので、将来的には再度サポートできることでしょう。でも、1.9 実装においては明らかに優先度が低くなっています。

ささだ さん(以下 ko1):

まつもと さんが旧モデルを説明しましたので、私は YARV のスレッドモデルを説明しましょう。

ご存知のように、YARV はネイティブスレッドをサポートします。つまり個々の Ruby スレッドを個別のネイティブスレッドで同時に実行できるわけです。

全ての Ruby スレッドが並列に実行できるという意味ではありません。YARVRuby スレッドが一つだけ実行されるグローバル VM ロック(グローバルインタプリタロック)です。C 言語で書かれた拡張の大部分を修正せずに実行できるため、この決定は恐らく我々を幸福にすることでしょう。


なぜ変更されたのでしょうか? グリーンスレッドは何が悪かったのですか?

Matz:

ネイティブスレッドを使用しているライブラリと一緒にはグリーンスレッドが上手く動きません。例えば Ruby/Tk は pthread と共に生存させるために多大なる労力が費やされています。

ko1:

Ruby のグリーン(ユーザレベル)スレッド実装は実行速度の面でナイーブ過ぎるのです。スレッドコンテキスト切替の際、マシンスタックが全てコピーされます。そして更に重要な点は、YARV でグリーンスレッドを再実装するのが簡単ではないことです :)


ネイティブスレッドアプローチの不利な点は何でしょうか?

Matz:

継続の実装が非常に難しいことです。それに加え、ネイティブスレッドアプローチでさえ、グローバルインタプリタロックのために真の並列処理は実現できません。ささだ さんは近々、マルチ VM アプローチでこの問題に取り組む予定です。

ko1:

はい、幾つか問題があります。先ずは性能の問題です(ご存知のように、私は性能に関して議論するのが大好きです)。ネイティブスレッドを作り過ぎるとコストが高くつきます。そのためスレッドプールなどを使うことでしょう。そして現在の trunk(YARV)はネイティブスレッドに関して調整されていないため、スレッド周りで何らかの未知の問題があると確信しています。

2番目の問題は移植性です。あなたの環境に pthread ライブラリがあったとしても、他の pthread システムとは細部で何らかの違いがあります。

3番目の問題はある人々にとって(グリーンスレッドスキームで実装される)callcc が無いことです。

ネイティブスレッドプログラミングはそれ自体が難しいものです。例えば、MacOS X では 他のスレッドが走っていると exec() が動きません(例外が生じます)。もしネイティブスレッドに致命的な問題を見つけた場合、trunk(YARV)でグリーンスレッドバージョンを作成することになるでしょう。


将来、他のスレッドモデルを採用する計画はありますか?

Matz:

他のスレッドモデルですか、無いですね。我々には Win32 スレッドと pthreads をサポートするだけでも十分負担です。将来、並列処理のサポートのために他の機能、例えば Erlang のような軽量プロセス、などがあるかもしれません。

ささだ さんはマルチ VM の専門家ですから、並列サポートに関する他のアイディアがあるかもしれません。

ko1:

Ruby による並列コンピューティングは私の主な関心事の一つです。いくつかの方法がありますが、同期の問題があるため、現在の C 拡張ライブラリをサポートしつつ Ruby スレッドを一つのプロセス上で(Giant VM ロック無しに)並列実行するのは非常に困難です。

まつもと さんが言いましたが、一つのプロセス上に複数の VM インスタンスがあれば、これらの VM は並列に実行できます。近い将来このテーマに関して(研究課題として)作業する予定です。

ところで、最後の質問について、もしネイティブスレッドで余りに多くの問題があればグリーンスレッドを実装するつもりだ、と書きました。ご存知のように、ネイティブスレッドに対して幾つか有利な点(軽量スレッド生成など)があります。それは素敵なハックになることでしょう(参考までに、私の卒業論文はある特定の SMT CPU 用のユーザレベルスレッドライブラリの実装です)。

... この実装、関心のある方はいますか?

The Ruby VM: Episode III