C#は電気羊の夢を見るか?(引っ越し中)

dtiブログが閉鎖とのことでhttp://tanocs.blog.fc2.com/へ引っ越します。

GPGPUの高速化

今回の実装で高速化が程度できたっぽいので効果のあった方法をメモ


まず、以前より改善を続けていたtexture2d.getdata()は
もってくるテクスチャサイズは小さければ小さいほどよい。
少々計算が複雑になってもサイズを小さくするほうが効果がある。


そして意外と盲点だったのは、メモリの管理。
ループ内で呼び出している外部関数で巨大なメモリを使用している場合、
引数にrefキーワードを用いるだけで劇的な改善が見られた。

これに気を良くして、そんなに効果があるならと
newキーワードの対象となる配列の宣言を極力ループの外に放り出すと
それだけでかなり速度が改善された。


例:
for(int i = 0; i < src.length; i++){

int[] hoge = new src.getData();
}
上記ソースを
int[] hoge;

for(int i = 0; i < src.length; i++){
hoge = new src.getData();
}
とするだけ。

このsrc.getData()のサイズが数メガに及ぶような場合、メモリや可読性が許せば
高速化のためにグローバル化(メンバ化)してしまうのも良いかもしれない。


本来ローカル変数はスコープが外れると無効にはなるものの、
ガベージコレクタさんが動くまでは、事実上はメモリを使用してる。

いつ動くかよくわからないガベージコレクタさん。
気がつくと多くの未使用メモリが増えることが多いのではないだろうか。
そしてガベージコレクタさんのお仕事の量が大きくなると処理もそれなりに重くなるっぽい。

特に描画処理は最大で秒間に60回近く呼ばれている計算になり、
そいつをforで2重ループなんかしている日にゃ、なかなかときつい仕事になるわけだ。

上記の例のように露骨にnewされている場合は気が付きやすいけど、
関数の引数もメモリを食っているので注意が必要。


あくまで一例だが、私の場合、5万近くの要素数になる配列の宣言を
メンバ化して計算用関数の引数をref化した結果15fps→60fpsと劇的な改善が見られた。

ただ、ゲームクラスのメンバにモデルの頂点データがいるのは実に気持ちが悪い。
計算用のグローバルだと思おう・・・


ここの記事によるとtexture2dをフリップ化することで
GPUとCPUで並列処理が可能になるとのことで、
もう少し処理の高速化が必要になったら試してみたい。

実は今回結局MRTで2回テクスチャの取得処理を発行しているが、
テクスチャフリップの際は2パスへの変更が必要だろうなと思う。
このエントリーをはてなブックマークに追加
LINEで送る

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://t01a.dtiblog.com/tb.php/122-80f81e41

« 小ネタ  | HOME |  GPGPUの現状 »

PAGE TOP ▲

Appendix

■春条

■春条

生息地は愛知
車と甘い物が好きな31歳
特技は無限昼寝

MONOからSharpDXを使う
変態的な手法で、
.NET Frameworkを使わずに
ゲーム作りやってます。

Search

Calender

« | 2018-08 | »
S M T W T F S
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -

Twitter

Recent Entries

DTIブログポータルへ
このブログを通報
Report Abuse

利用規約