Ruby側の最適化

必要メモリ帯域は大幅に減らした。
うちには遅いPCは無いから実際どのレベルまで動くようになっているのかはわからないが、半透明フィルタ100枚かぶせた時の動作は軽くなったから効果はあるはずだ。
どうしてそういう判断になるかというと、半透明フィルタのデータ量は一定で、DXRubyではサイズにかかわらず100個程度の画像描画は問題にはならないからだ。
それが100個で重いということは、GPUピクセルフィルレートかメモリ帯域がネックになっているはずで、1ピクセルのデータを引き伸ばして軽くなったということは、ピクセルフィルレートが原因ではなく、ビデオメモリの帯域の限界だったということになる。
よって、この場合の重い現象はメモリ帯域がネックになっていて、それが軽くなったのだからメモリ帯域の消費量が減っているわけだ。
もっと減らすなら、背景の塗りつぶしをDXRubyの背景クリアにやらせて、チップとして部分的に描画する方法もあるが、面倒なうえに大きな効果が見込めないから見送った。
っていうかむしろ全画面描画するならDXRubyの背景クリアをカットしたいところだが、そんな機能は付けていない。
ライブラリ側の最適化オプションみたいなのはあまり追加したくないのだ。
難しくなるから。
背景クリアの実態はフレームバッファに対するハードウェア転送だろうから、GPUピクセルフィルレートが食われるだけで、そっちがボトルネックになることは無いと考えている。
足りていないのはテクスチャ転送のメモリ帯域なのだ。
だからビデオメモリ搭載のビデオカードを使っていれば、かなり古いPCでも動くはずで、俺が昔苦労してたのも内蔵チップセットを使ったPCだった。
こういうことを考えていると、遅いPCで動かすのに必要なのはライブラリのスペックではなく、ゲーム側の負荷軽減努力だと言うことがわかってくる。
が、それを万人に説明するわけにも、理解してもらうわけにもいかず、サンプルシューティングはDXRubyのマーケティング用ゲームなわけで、動かした人に「お?」と思わせ、「使ってみよう」と行動させるのが目的なのだから、フェイクだろうがペテンだろうが徹底的にやる。
それがサンプルゲームの存在意義だからだ。


さて、んでここからが本題。
DXRubyのターゲットは一応Pentium4クラスということにしてはいるが、余裕があるからNetBurstアーキテクチャのローエンドぐらいまで広げて考えたいところだ。
ローエンドといえばceleronになるが、NetBurstアーキテクチャ採用のceleronの最低は1.4GHz。
うちのPCの半分を下回るぐらいだろうか。
近い世代のceleronで周波数だけならBaniasコアの900MHzがあるが、こいつはアーキテクチャが違って効率いいから1.4GHzのNetBurstとさほど変わらないだろう。
まあ、言うまでもなく動かすゲームとその作りによる部分のほうが大きいわけだが。
Ruby遅いし。


サンプルシューティングはその存在意義から、CPUのスペックも下限を攻めないといけない。
exe化したらわかんないからCライブラリで動かしてしまえ、とかはウソだから論外。
それ以外で、正当にRubyを使うなら、どんな手を使うのもアリだ。
ソースも公開だし。
一番手っ取り早いのはRuby1.9.1を採用することなんだろうが、Exerbに1.9.1コアが無いからできないのだな。
んで、それ以外でどーやってRuby側の動作速度を稼ぐかという話になる。
簡単なのはゲーム中に出てくる弾の数を減らすことだが、それをやってしまうと話が終わってしまうので、ここではゲーム自体を変更しないでいかに速くするか、と考える。
逆に言えば、最も負荷が上がるのはボスの弾と自分の弾が最大数飛びまわる瞬間であり、ザコ部分ではほとんど負荷になっていない。
当たり判定負荷から考えると自分の弾とザコの判定が一番痛いはずなのだが、そうではないのはDXRubyExtensionの効果だ。
全く関係ないのだが、DXRubyMapぽいもので高速バッチ描画ライブラリとかできるかもしれないな、とふと思った。
さて、結局のところ、大量の弾を動かす&描画する部分を少しでも軽くできれば、最大負荷は下がるわけだ。
Rubyの遅い原因はメソッド検索だから、計算式などで使っているメソッド呼び出しを極限まで減らすようにすれば単純に速くなる。
Cコンパイラみたいに最適化はしてくれないから、自分でメソッド呼び出しが最小になるように考える必要がある。
Rubyでの最適化はそれが基本であり、それが全てだ。もっとトリッキーな最適化はこれから研究しよう。面白いから。
で、そのように努力してみたところ、ボスの弾の時で自分が弾を撃ちまくっていても、ほぼ20%台に収まるところまできた。
ここまでやればCPU負荷的には5年前のローエンドでも行けるだろう。GPUは別だ。
ちなみにDXRubyはWindow.drawExが遅いから、オプションの弾の回転&縮小しているのを、小さい絵を描いて回転のみにすれば最大負荷が3%ぐらい減る。
しかしチャレンジはしてみたものの、小さい絵がうまく描けなかったから諦めた。
プログラミングだけに限らず、技術不足でスペックが下がるのは悔しい。