ノートの端の書き残し

UnityやらC#やら。設計が得意かもしれない。

ゲーム開発の最適化の最頻パターン

チームで開発してて、なんか色々レガシーなものがあったり気に食わない部分があったりするプロジェクトに携わる雑用プログラマの経験則です。
具体的なプロジェクトの内容に依らず、第一原因はこれだろうと思うやつを挙げました。

CPU編

ヒープアロケーション(GCAlloc)

問題

最適化はプロファイラを見て行えといった、一般的に正しいとされているものはやはり正しいです。
さて、プロファイラを見る際に、デバッグビルドだと処理時間が正確に出ないので、100%信用できないなと思うことはあると思います。
そういう時は、とりあえず高頻度で発生しているGCAllocを潰しましょう。
実際に改善したいのは実行時間なんですが、ヒープにメモリを確保するのは大抵の数値計算なんかより遥かに重いです。
デバッグビルドにおいてはメソッド呼び出しのオーバーヘッドが加算されますが、メモリは誤差がありません。
「100万回ループが毎フレーム走ってる」ような明らかな計算負荷があるならそれを優先すべきですが、GCAllocを潰しておいて損は無いです。

あと、これは若干偏見が入った経験則なんですが、効率の悪い計算が行われている場合、大抵GCAllocも大きく発生しています。今のところ人間がプログラムを書いているし、AIも所詮は人間のプログラムを学んでいるだけの段階ですから、現代の製品コードにおいて「アルゴリズムは最悪だけどGCAllocはゼロ」みたいな奇跡はあんまり無いです。できる人はどっちもできるし、できない人はどっちもできない。
最適化すべきポイントの目印だと思っても差し支えないでしょう。

対策

オブジェクトプールしましょう。大した機能は要りません、Stack<T>に入れて取り出すだけの単純なもので十分です。
あと、言語の特徴を掴みましょう。計算中に、メモでしかない配列を生成していませんか?毎フレームLINQをたくさん走らせたりしてないでしょうか。メソッドを分けて、適切に名前をつけてあげれば、forループの読みづらさ程度ならカバーできます。

GPU

フィルレート

問題

解像度を落として劇的に改善する場合、単純に塗ってるピクセル数が多いです。あまり詳しくない場合、その原因は大抵、半透明のオブジェクトを大量に生成して、画面いっぱいに何枚も重ねていることです。ぱっと見透明にしか見えないのにGPUは健気に計算してくれます。

対策

オブジェクト減らしましょう。もしくは、半透明オブジェクトだけ解像度を下げましょう。 game.watch.impress.co.jp

古くは2007年頃に発明された手法ですが、今でも十分現役です。ゲームエンジンがデフォルトで対応していない場合レンダリングパイプラインの改造が必要になりますが、考え方自体はシンプルです。