告知欄です
1- レス

管理人の雑記


[128]管理人 ★:2009/05/04(月) 04:59:34
>>124をマルチスレッドに対応させるなどした。
SpiderMonkeyをマルチスレッド対応させる上で主に注意すべきなのが、GCのタイミングであるらしい。
あるスレッドが何かに使うためにオブジェクトを生成して、他から参照されている状態にする前に、他のスレッドでGCが実行されてしまうと、使うはずだったオブジェクトが解放されてしまう恐れがある。
そこで、リクエストという仕組みで、スレッドがJSAPIの処理中であることを通知して、GCが発生しないようにしておく必要があるらしい。
GCが必要になると、他の全てのスレッドのリクエストが完了/中断されてGC可能状態になるまで待ち合わせてから、GCが実行されるらしい。
オブジェクトなどへのアクセスは、排他制御が行われるので、複数スレッド間で共有しても問題無いらしいが、共有オブジェクトへのアクセスが多発すると、待ち合わせが多発して効率は落ちるようだ。
大体の仕組みが分かったので、まず既存のコードにJS_[Begin/End]Request()などの処理を追加した。
次に、マルチスレッドでスクリプトを実行できるようにする。
とりあえず、別途作成したJSAPIコンテキストを使い、新規スレッドで指定のスクリプトを実行するという関数を用意してみた。
また、関数をネイティブコード側から呼べるようエクスポートする関数に、不特定多数のスレッドから呼ばれても大丈夫なようにする機能を追加。新規コンテキストを生成するコストが大きいため、従来方式と選択可能にした。
前者はグローバルオブジェクトも新規作成するが、後者は元のコンテキストのグローバルオブジェクトをそのまま利用する。
とりあえず、以前の1から60万までを文字列として連結する処理を2つのスレッドで実行させてみたところ、異様に遅くなった。
両方のバージョンとも速度は大差ないので、問題なのはGCの待ち合わせのようだ。
文字列やオブジェクトをあまり生成しないであろう素数探索処理を並列実行させたところ、シングルスレッドの時とほとんど同じ速度で実行された。(マルチコア環境なので)
コンテキスト作成版と関数エクスポート版での速度差はあまり見られない。
グローバルオブジェクトを共有すると、文字列やオブジェクトの操作時にも共有部分へのアクセスが発生して遅くなるかと思ったが、それほど問題にはならないようだ。
関数エクスポート版では、グローバル変数や関数が生成されたスコープでの変数にも普通にアクセスできるので、利便性が高い。
実際にマルチスレッド処理が必要になるのは、処理時間のかかるAPIの実行中に他の処理を行わせたい場合等だろうから、GCによる効率の低下はそれほど気にする必要はないだろう。
どうしてもそのような処理を並列実行させたい場合は、プロセス自体を並列化させればいい。


名前

E-mail



0ch BBS 2005-10-08