5870性能評価(1)

ComputeShaderでGPUの性能を測定しようと四苦八苦してみたけど、処理が明らかに速すぎる…
処理結果を取りにいっていないせいか、処理そのものがスキップされてるのかも。レンダリングパイプラインへのコマンド発行も非同期的に行われているみたいだし、1発取りの処理時間測定方法だとダメかも。


仕方がないのでアプローチを変更して、DirextX11のサンプルに入っているBasicHLSL11を魔改造してFPSを測定することで間接的にGPUの性能を評価しようと思う。

今使っているGPURadeon HD5870で、カタログスペックだと2.72TFLOPSとのことなのでアプリケーションを動かした際にどこまで性能が出るのか見てみようと思う。



測定条件は以下の通り。

  • フルHD 60FPS
  • フルスクリーンモード
  • 1フレーム1ピクセルごとに何命令まで実行可能かを測定する
  • テクスチャアクセス量は最小限とする(純粋なコンピューティングパワーを測定)

具体的な測定方法は以下の通り

まずBasicHLSL11_PS.hlslを無駄に高負荷仕様に変更する
PSMain()を以下のように変更

#define NUM_LOOP 400
float4 PSMain( PS_INPUT Input ) : SV_TARGET
{
	float4 vDiffuse = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord );

	float fLighting = saturate( dot( g_vLightDir, Input.vNormal ) );
	fLighting = max( fLighting, g_fAmbient );

	// このカタマリを追加
	float4 tmp = g_fAmbient;
	[unroll]
	for(int i=0;i 0)? vDiffuse * fLighting : tmp;	// 代わりにこっちを追加
}

g_fAmbientは常に正の数なので処理結果は変わらないけど、NUM_LOOP*4くらい無駄な処理が追加される。このNUM_LOOPを調整してだいたい60FPSになる値を探る。
改造後のBasicHLSL11_PS.hlslは.exeと同じディレクトリに入れておく。(そうすることで改造版の.hlslファイルが優先的に使われる)



次にモデルデータを差し替える
tinyのモデルだと何ピクセル分処理が実行されているのか判別しにくいので長方形の板きれモデルを作って、それを全画面に映るようにBasicHLSL11.exeを実行中にマウスで位置調整する。
モデルデータは.xファイルをUtilities\bin\x64\MeshConvert.exeで.sdkmeshに変換して.exe配下のtiny\tiny.sdkmeshとして保存。(同じくexe配下が優先される)

>Utilities\bin\x86\MeshConvert.exe /o Samples\C++\Direct3D11\Bin\x64\tiny\tiny.sdkmesh simple_rectangle.x

このとき、.xファイルで指定するテクスチャファイルはサイズが1ピクセルとか小さいファイルを指定しておく。テクスチャファイルもexe配下のtinyディレクトリに入れておく。(ちなみにテクスチャファイルを入れ忘れるとBasicHLSL11.exeがクラッシュする(^^;)





という方法で、

  • NUM_LOOPを変更
  • BasicHLSL11.exeを実行
  • フルスクリーンに変更してマウスでモデルが全ピクセルを覆うように位置調整
  • しばらく眺めてFPSを目視で測定

を繰り返してだいたい60FPSになるNUM_LOOPを探してみた。


結果としては、NUM_LOOP=400(2006命令)のときに62FPSになった。
1920×1080×62×2006=258G命令/secで、カタログスペックとの差は約5%だった(!)

ちなみにカタログスペックの2.72TFLOPSはFMAD命令を2FLOPSと数えた上にxyzwの4要素をSIMD演算した場合を4FLOPSと数えて使用頻度が低そうな特殊演算器(sin/cosとかの)も同時に動かした場合を想定しているので(4+1)×2=10FLOPS/命令って感じで数えてる。ので、命令/secの単位に直すと2.72T/10=272G命令/sec。


まさか、こんなに簡単にカタログスペックをたたき出せると思っていなかったのでびっくり(^^; あと、今回使った範囲の命令はスループット1っぽい。(1より大きいならもっとFPSが落ちるので)
それにしても、カタログスペックと実態は一ケタくらい違うものだと思っていたのでかなり意外。逆に考えると、コンピューティングパワー的には2000命令/pixel・フレーム出せるので、フルHDで60FPS出ない場合はどこかがボトルネックになってるってことになる。(どう考えてもポストプロセスが重いって言ってもさすがに1pixelあたり2000命令も逝かないはず。てか、1000命令すら逝かないと思われ。Vertex処理なんてPixel処理と比べたら処理回数が2ケタは少ないので無視できるレベルだし)


注目すべきはこんな簡単なアプリケーションですら5%もオーバーヘッド(と思わる)があることかもしれない。多数のフレームに分割された複雑なモデルとかになると激重になったりしないか心配。その辺は今後の性能評価で見ていきたいなぁ。


ちなみにNUM_LOOPを400より大きくすると250G命令/secに逝かなくなったんだけど、なぜだろう…ちょっと気になる。