Threadを勉強してみた
書くことがないとか言うと書くことが思い浮かぶ不思議・・・
最近、スクリプトの計量化に限界を感じてきたので、今まで使ったことのない機能を勉強しようと思い、そこで目をつけたのがThreadクラスというもの。
名前の通り、スレッドを作るクラスです。
並行プログラミングを可能とするクラスで、つまりはこれにより複数のCPUコアでプログラムを制御する事ができます。
これを身につければ、従来より軽量で多くの処理を行えるんじゃないかと考えたわけです!
(・・・ちなみにRubyに詳しい方なら、この時点で間違ってることに気づくでしょう。
つまり、そういうお話です)
以前、並列処理を行えるクラスとしてFiberについて書きましたが、あれはプログラムの合間に別の処理を割り込ませる感じです。
こちらの並行処理は、本当に同時に処理を行うらしいです。
例えば、
(joinというのは、スレッドの処理が終わるまで待つメソッドです)
普通に考えると、a は 2 という答えになるはずです。
が、並行処理はこの二つの a += 1 を別々に行うため、2 になることもあれば 1 になることもある
・・・らしいです。(って書いてありました。私は確認してません)
で、これを解決するのが Mutex というクラス。
この Mutex は片方のスレッドでロックをかけると、もう片方のスレッドからはロックできず、ロックが解除されるまでいったん処理を止めてくれるというものです。
スクリプトで書くとこんな感じ。
これで、a += 1 は片方が終わるまでもう片方は処理されません。
ちゃんと a が 2 という答えを出します。
で、この lock ~ unlock は synchronize { } と簡単なものに置き換えれるようです。
・・・が、ここでエラーが発生。
しかも内容は NoMethodError
つまり、Mutex クラスに synchronize なんてメソッドは存在しないよ!ってことです。
訳わかりません。
RGSS3はRuby1.9.2のはずだし、1.9.2には synchronize があるはずです。
試しに methods で定義されているメソッドの配列を表示してみたら、確かに synchronize だけがありません。
結局原因は不明です。
とりあえず、RGSS3の Mutex クラスに synchronize がないのは確かです。
ホントなんででしょう・・・?
話を戻します。
で、これで早速スクリプトの計量化に取り組んだわけですが、なかなかうまく行かない。
RGSSは Graphics.update で1フレームの更新が行われるので、新しく作ったスレッドはこれと同期させなければなりません。
ですが、Mutexは同時に実行するのを防ぐためのものなので、同期をとるのには適していないからです。
ならば、別の方法を考えるしかない。
そこで考えたのが、Thread.stopによる処理の停止と、wakeupによる停止状態の解除です。
こんな感じで組めば、1フレームごとに a を +1 してくれるはずです。
で、これをツクールでやってみたところ、見事同期させることに成功しました!
・・・が、
計量化どころか、明らかにフレームレートが落ちています。
Rubyのスレッドは重いとはどこかで見ましたが、さすがに複数コアでの処理でこれは重すぎるだろう・・・
てか、本当に複数コアで処理してるのでしょうか?
と気になり調べてみましたが、プリエンプティブだかノンプリエンプティブだかグリーンスレッドだかネイティブスレッドだか・・・
私はそういうの、さっぱりわかりません。
ですが、実際に1つのスレッド処理と2つのスレッド処理にかかる時間を比べたものがあり、それによると2つの時は1つの時の倍近い時間がかかるというものでした。
つまり、Rubyは複数コアのCPUでも1つのコアしか使ってないと・・・
実際に私も自家製ベンチマークで処理にかかる時間を測ってみました。
結果・・・
ほんとに2倍の時間がかかってました。
つまり、RGSSではThreadクラスを使っても処理が重くなるだけで、計量化には使えない!
――という、勉強した意味がなかったというお話でした。
でも、将来Threadクラスが複数コアに対応するかもしれないし、
そして次のツクール(出るかどうかは知りません)に最新のRubyが採用されれば、この知識も無駄にはならないでしょう!
そうなるといいな。
最近、スクリプトの計量化に限界を感じてきたので、今まで使ったことのない機能を勉強しようと思い、そこで目をつけたのがThreadクラスというもの。
名前の通り、スレッドを作るクラスです。
並行プログラミングを可能とするクラスで、つまりはこれにより複数のCPUコアでプログラムを制御する事ができます。
これを身につければ、従来より軽量で多くの処理を行えるんじゃないかと考えたわけです!
(・・・ちなみにRubyに詳しい方なら、この時点で間違ってることに気づくでしょう。
つまり、そういうお話です)
以前、並列処理を行えるクラスとしてFiberについて書きましたが、あれはプログラムの合間に別の処理を割り込ませる感じです。
こちらの並行処理は、本当に同時に処理を行うらしいです。
例えば、
a = 0
t1 = Thread.new do
a += 1
end
t2 = Thread.new do
a += 1
end
t1.join
t2.join
p a
という処理を行った場合。t1 = Thread.new do
a += 1
end
t2 = Thread.new do
a += 1
end
t1.join
t2.join
p a
(joinというのは、スレッドの処理が終わるまで待つメソッドです)
普通に考えると、a は 2 という答えになるはずです。
が、並行処理はこの二つの a += 1 を別々に行うため、2 になることもあれば 1 になることもある
・・・らしいです。(って書いてありました。私は確認してません)
で、これを解決するのが Mutex というクラス。
この Mutex は片方のスレッドでロックをかけると、もう片方のスレッドからはロックできず、ロックが解除されるまでいったん処理を止めてくれるというものです。
スクリプトで書くとこんな感じ。
a = 0
m = Mutex.new
t1 = Thread.new do
m.lock
a += 1
m.unlock
end
t2 = Thread.new do
m.lock
a += 1
m.unlock
end
t1.join
t2.join
p a
m = Mutex.new
t1 = Thread.new do
m.lock
a += 1
m.unlock
end
t2 = Thread.new do
m.lock
a += 1
m.unlock
end
t1.join
t2.join
p a
これで、a += 1 は片方が終わるまでもう片方は処理されません。
ちゃんと a が 2 という答えを出します。
で、この lock ~ unlock は synchronize { } と簡単なものに置き換えれるようです。
a = 0
m = Mutex.new
t1 = Thread.new do
m.synchronize { a += 1 }
end
t2 = Thread.new do
m.synchronize { a += 1 }
end
t1.join
t2.join
p a
m = Mutex.new
t1 = Thread.new do
m.synchronize { a += 1 }
end
t2 = Thread.new do
m.synchronize { a += 1 }
end
t1.join
t2.join
p a
・・・が、ここでエラーが発生。
しかも内容は NoMethodError
つまり、Mutex クラスに synchronize なんてメソッドは存在しないよ!ってことです。
訳わかりません。
RGSS3はRuby1.9.2のはずだし、1.9.2には synchronize があるはずです。
試しに methods で定義されているメソッドの配列を表示してみたら、確かに synchronize だけがありません。
結局原因は不明です。
とりあえず、RGSS3の Mutex クラスに synchronize がないのは確かです。
ホントなんででしょう・・・?
話を戻します。
で、これで早速スクリプトの計量化に取り組んだわけですが、なかなかうまく行かない。
RGSSは Graphics.update で1フレームの更新が行われるので、新しく作ったスレッドはこれと同期させなければなりません。
ですが、Mutexは同時に実行するのを防ぐためのものなので、同期をとるのには適していないからです。
ならば、別の方法を考えるしかない。
そこで考えたのが、Thread.stopによる処理の停止と、wakeupによる停止状態の解除です。
a = 0
t = Thread.new do
loop do
Thread.stop
a += 1
end
end
loop do
Graphics.update
t.wakeup
end
t = Thread.new do
loop do
Thread.stop
a += 1
end
end
loop do
Graphics.update
t.wakeup
end
こんな感じで組めば、1フレームごとに a を +1 してくれるはずです。
で、これをツクールでやってみたところ、見事同期させることに成功しました!
・・・が、
計量化どころか、明らかにフレームレートが落ちています。
Rubyのスレッドは重いとはどこかで見ましたが、さすがに複数コアでの処理でこれは重すぎるだろう・・・
てか、本当に複数コアで処理してるのでしょうか?
と気になり調べてみましたが、プリエンプティブだかノンプリエンプティブだかグリーンスレッドだかネイティブスレッドだか・・・
私はそういうの、さっぱりわかりません。
ですが、実際に1つのスレッド処理と2つのスレッド処理にかかる時間を比べたものがあり、それによると2つの時は1つの時の倍近い時間がかかるというものでした。
つまり、Rubyは複数コアのCPUでも1つのコアしか使ってないと・・・
実際に私も自家製ベンチマークで処理にかかる時間を測ってみました。
結果・・・
ほんとに2倍の時間がかかってました。
つまり、RGSSではThreadクラスを使っても処理が重くなるだけで、計量化には使えない!
――という、勉強した意味がなかったというお話でした。
でも、将来Threadクラスが複数コアに対応するかもしれないし、
そして次のツクール(出るかどうかは知りません)に最新のRubyが採用されれば、この知識も無駄にはならないでしょう!
そうなるといいな。
スポンサーサイト
キャラクターメイクとスクリプト更新
【キャラクターメイク】
ツクールVXAceに付属しているキャラクター生成をゲーム内で行えるようにします。
なんか無駄に面倒くさいスクリプトになってしまった気がする・・・
デフォルトではほとんどの機能が設定可能になってますが、必要に応じて減らしたほうがいいと思います。
ついでに以下のスクリプトを更新。
装備変更コマンドの削除
以前書いた、競合が起きにくくなるような処置を取りました。
とりあえず作りたいものは作ったので、「箱庭の勇者たち」の製作に入ろうと思います。
他の更新してないスクリプトにつきましては、また思いついたら作ります。
体験版からいろいろと変更したいところがあるので、完成まではまだまだかかりそうです。
それから、ゲーム作ってるとブログに書くことが無くなるので、更新も下がることになります。
そんな感じで、気張らず気ままに頑張ろうと思います。
それにしても本当に暑い・・・(;´д`)
ツクールVXAceに付属しているキャラクター生成をゲーム内で行えるようにします。
なんか無駄に面倒くさいスクリプトになってしまった気がする・・・
デフォルトではほとんどの機能が設定可能になってますが、必要に応じて減らしたほうがいいと思います。
ついでに以下のスクリプトを更新。
装備変更コマンドの削除
以前書いた、競合が起きにくくなるような処置を取りました。
とりあえず作りたいものは作ったので、「箱庭の勇者たち」の製作に入ろうと思います。
他の更新してないスクリプトにつきましては、また思いついたら作ります。
体験版からいろいろと変更したいところがあるので、完成まではまだまだかかりそうです。
それから、ゲーム作ってるとブログに書くことが無くなるので、更新も下がることになります。
そんな感じで、気張らず気ままに頑張ろうと思います。
それにしても本当に暑い・・・(;´д`)
日記
まずは前回、Vectorさんの方でコメントできるようにするの放置するとか書きましたが、言ったそばからできるようにしました。
というのも、Vectorさんで記事を書いてくださった方が、ブログを見てパスワードをわざわざ送ってくださったのですよ。
ただ、そのパスワード実は・・・
書きにくいので割愛w
ま、とにかくいろいろあって、コメントできるようになりましたとさ。
製作中のスクリプトはようやく形になってきたので、中途報告。
まずはスクリーンショット。
(ただし、まだ製作途中ですので、内容は変わる可能性があります)


スクリプト名は「キャラクターメイク」といったところでしょうか。
簡単にいえばVXAceについているキャラクター生成を、ゲーム内で行えるようにしたものです。
せっかくなので、それに二つ名選択やら職業選択やらを付けてみました。
顔グラフィックについては、既に完成したものからの選択になります。
理由は単純にあの顔グラ生成が好きじゃないのと、好きじゃないからわざわざ再現したくないってのが理由です。
なので、顔グラフィックを使わないようなゲーム向きかもしれません。
ただ、問題もまだまだ色々とあります。
まずは「装備変更コマンドの削除」との競合。
これは「装備変更コマンドの削除」の方をいつか修正したいと思います。
もともとあっちは競合が起きやすい内容ですので、何とかしないといけないとは思っていました。
もし、何らかの理由でカーソルの動きがおかしくなる場合、たいていこの「装備変更コマンドの削除」が原因だと思うので、いったん削除することをおすすめします。
次の問題がスクリプト量。
まだ半分を超えたくらいなのに、もう乗り物疑似3D化と同等の規模になっとります。
設定項目部分だけで、既に400行いってる状態。
乗り物疑似3D化みたいに、オプションとして分割すべきかどうか迷っています。
ちなみにこのスクリプト、部位ごとのパーツを変えられる機能を応用して、装備でパーツを変更することも可能にする予定です。
つまり、胴装備で服が変わったり、マント装備したらキャラクターもマントつけたりとか出来るかも。
むしろ、キャラメイク画面いらないから、こっちだけ使いたいって人いるかもしれません。
これも分割しようかと思う理由の一つです。
最後の問題が超深刻。
画面のレイアウトが思い浮かばない!
・・・なにげに一番時間のかかっている部分です。
スクリプトしか能がなく絵心の欠片もない私には、画面のレイアウトはかなり苦手分野だったり。
今のところ、スキル画面を参考にした面白みのないレイアウトになっております。
既に設定項目も山のようになってしまっているので、ウィンドウの位置を設定できるようには作っていません。
気に入らない方は、自力でスクリプトいじってもらうことになります。
というわけで、「キャラクターメイク」鋭意作成中です!
私もいつかこれ使ってゲーム作りたいと妄想しております。
以下コメントお返事です。
というのも、Vectorさんで記事を書いてくださった方が、ブログを見てパスワードをわざわざ送ってくださったのですよ。
ただ、そのパスワード実は・・・
書きにくいので割愛w
ま、とにかくいろいろあって、コメントできるようになりましたとさ。
製作中のスクリプトはようやく形になってきたので、中途報告。
まずはスクリーンショット。
(ただし、まだ製作途中ですので、内容は変わる可能性があります)


スクリプト名は「キャラクターメイク」といったところでしょうか。
簡単にいえばVXAceについているキャラクター生成を、ゲーム内で行えるようにしたものです。
せっかくなので、それに二つ名選択やら職業選択やらを付けてみました。
顔グラフィックについては、既に完成したものからの選択になります。
理由は単純にあの顔グラ生成が好きじゃないのと、好きじゃないからわざわざ再現したくないってのが理由です。
なので、顔グラフィックを使わないようなゲーム向きかもしれません。
ただ、問題もまだまだ色々とあります。
まずは「装備変更コマンドの削除」との競合。
これは「装備変更コマンドの削除」の方をいつか修正したいと思います。
もともとあっちは競合が起きやすい内容ですので、何とかしないといけないとは思っていました。
もし、何らかの理由でカーソルの動きがおかしくなる場合、たいていこの「装備変更コマンドの削除」が原因だと思うので、いったん削除することをおすすめします。
次の問題がスクリプト量。
まだ半分を超えたくらいなのに、もう乗り物疑似3D化と同等の規模になっとります。
設定項目部分だけで、既に400行いってる状態。
乗り物疑似3D化みたいに、オプションとして分割すべきかどうか迷っています。
ちなみにこのスクリプト、部位ごとのパーツを変えられる機能を応用して、装備でパーツを変更することも可能にする予定です。
つまり、胴装備で服が変わったり、マント装備したらキャラクターもマントつけたりとか出来るかも。
むしろ、キャラメイク画面いらないから、こっちだけ使いたいって人いるかもしれません。
これも分割しようかと思う理由の一つです。
最後の問題が超深刻。
画面のレイアウトが思い浮かばない!
・・・なにげに一番時間のかかっている部分です。
スクリプトしか能がなく絵心の欠片もない私には、画面のレイアウトはかなり苦手分野だったり。
今のところ、スキル画面を参考にした面白みのないレイアウトになっております。
既に設定項目も山のようになってしまっているので、ウィンドウの位置を設定できるようには作っていません。
気に入らない方は、自力でスクリプトいじってもらうことになります。
というわけで、「キャラクターメイク」鋭意作成中です!
私もいつかこれ使ってゲーム作りたいと妄想しております。
以下コメントお返事です。
いろいろ報告とお返事
Vectorさんでソフト紹介の記事を書いて頂きました。
こちらからレビューページヘと飛べます。
こういった感想をじっくりと読むのは嬉しいと同時に恥ずかしいですね!
私のコメントも載ってます。
ぜひ読んでみてください!
そういえばちょっと話し変わりますが、Vectorさんで公開している「ぼくらの大革命!」、未だにコメント出来るようにしてなかったり。
関連付けをする必要があるのですが、パスワードを忘れたのでそのまんま放ったらかしにしてたというのが理由ですw
いまさら出来るようにしてもなあ・・・ってのがあるので、やっぱり放置したままになりそうです。
スクリプト素材に関して。
ちょっと思った以上にスクリプトの進みが悪いので、いろいろと後回しや凍結といったことになりそうです。
今作ってるものは、作りたいという気持ちが強いので完成するまで粘りますが、乗り物疑似3D化VXverの更新やマップ表示はちょっと手を付けるのすらいつになるかわかりません。
で、何を作っているのかというと・・・
それすらまだ書けないくらい、完成の目処が立たない状態です。
以下、コメントお返事です。
こちらからレビューページヘと飛べます。
こういった感想をじっくりと読むのは嬉しいと同時に恥ずかしいですね!
私のコメントも載ってます。
ぜひ読んでみてください!
そういえばちょっと話し変わりますが、Vectorさんで公開している「ぼくらの大革命!」、未だにコメント出来るようにしてなかったり。
関連付けをする必要があるのですが、パスワードを忘れたのでそのまんま放ったらかしにしてたというのが理由ですw
いまさら出来るようにしてもなあ・・・ってのがあるので、やっぱり放置したままになりそうです。
スクリプト素材に関して。
ちょっと思った以上にスクリプトの進みが悪いので、いろいろと後回しや凍結といったことになりそうです。
今作ってるものは、作りたいという気持ちが強いので完成するまで粘りますが、乗り物疑似3D化VXverの更新やマップ表示はちょっと手を付けるのすらいつになるかわかりません。
で、何を作っているのかというと・・・
それすらまだ書けないくらい、完成の目処が立たない状態です。
以下、コメントお返事です。