「リアルタイムレンダリング 第2版」

やっと、90%くらい目を通しまた。もう少しで読み終わりそう。

●「第10章 パイプライン最適化」の中で得られたこと


画像をレンダリングする処理はアプリケーション、ジオメトリ、ラスタライザの3つの概念的ステージを持つパイプラインアーキテクチャに基づいています。
 ただし、パイプラインの3つのステージへの分割は概念的な分割です。アーキテクチャによっては本当のパイプラインステージは違って見えるかもしれません。例えば場合によってはアプリケーションステージとジオメトリステージが両方とも1つのCPUで実行されるので最適化するときには1つのステージとして扱うべきです。 

【アプリケーションステージ】
 CPU律速(CPU-limited)
 アプリケーションステージが暇な場合、よりリアルなアニメーション計算する、より正確な衝突検出を実装する


【ジオメトリステージ】
  ライティング、テクスチャ座標生成、フォグなどはジオメトリステージ内で行われます。
  座標変換律速(transform-limited)
  ジオメトリステージが暇な場合、より多くのライトやより高価な光源の型を使う、より高負荷な頂点シェーダプログラムを使ってもよい


【ラスタライザステージ】
  ブレンディング処理、Zバッファ処理、ステンシルバッファ処理など
  塗りつぶし律速(fill-limited)
  ラスタライザステージが暇なら、より高価なテクスチャフィルタ処理、フォグ、ブレンド処理、ピクセルシェーダなどを使う。


塗りつぶすピクセルの数が変わらない限り、塗りつぶし律速アプリケーションはラスタライザステージに影響を与えることなく容易にポリゴン数が増やせます。言い換えると同じオブジェクトをより多くの三角形デ表現できます。一方座標変換律速アプリケーションではジオメトリステージをすぴオードアップするために塗りつぶす(フィル)べきピクセルの数に影響を与えることなく三角形の数を減らせます。

塗りつぶし律速でなければ画像を描画するウィンドウを拡大できます。


【ボトルネック】
最も遅いステージ(ボトルネック)が実際の速度を決定します。

いつの時点でもボトルネックがあり、このボトルネックがアプリケーションの速度の限界を設定します

パイプライン構造のもう1つの活用の仕方は最も遅いステージをそれ以上最適化できないときに他のステージを最も遅いステージと全く同じだけ動かせばよいことを認識することです。最も遅いステージの速度は変わらないので、これによって性能は変わりません。



【CPUの限界速度をテストする賢い方法】
 本当のドライバ(ライブラリ)の代わりにヌルドライバ(呼び出しは受け入れるが何もしないドライバ)を使うだけで実現できます。


【SIMD(Single Instruction Multi Data:単一命令複数データ)】
 通常2~4成分を並列に計算できるのでベクトル演算に最適です。AMDの3DNow!


【除算は使用を可能な限り避けます。】
 通常この命令は他ののほとんどの命令の4倍から39倍の実行時間がかかります。
 除算の変わりに逆数を計算してから、乗算するほうが高速です。

小さなループは展開(unroll)します

PCでは頻繁に使うデータ構造を性格に32バイトの倍数に揃えるとキャッシュラインを最適に使うことによって全体の性能を大きく改善できます。

コンパイラが最適化用のヒントとしてなるべくrestrict(Cでポインタの別名を避ける)とconstを使う

頻繁に呼ばれる小さな関数はインラインコードを使います

システムによってはmalloc()とfree()が遅いので、しばしば開始時に大きなメモリプールを割り当て、専用の割り当てルーチンと解放ルーチンを用意する自前メモリ管理を行うといい


【深度複雑性】
 深度の複雑さとは各ピクセルが上書きされた回数

【深度複雑性の画像を生成する方法】
 Zバッファを無効にしてOpenGLのglBlendFunc(GL_ONE,GL_ONE)のような呼び出しを使うことです。まず、画像を黒でクリアします。次にシーン内のオブジェクトを色(0,0,1)でレンダリングします。をのブレンド関数設定の効果はプリミティブのレンダリングごとに書かれたピクセルの値(0,0,1)ずつ増やすことです。深度複雑性が0のピクセルは黒で深度複雑性が255のピクセルは完,0,255)です。


【繰り延べシェーディング(deferred shading)】
 シーンの最初のパスでは、そのサーフェスをZバッファにだけレンダリングします。シーン全体をレンダリングしてZバッファを固定した後、そのサーフェイスをピクセルシェーダ付きでレンダリングします。ピクセルフラグメントがピクセルシェーダに到達する前に遮蔽カリングハードウェアによって見えないピクセルを排除できるので、かなりの量のフィルレートの節約になります。
ただし、ピクセルシェーダがZバッファを変更する場合にはこの早期排除を使えないことに注意してください。

【モニタの周波数】
72Hzの場合、t=1/72=0.01389秒=13.89ミリ秒かかることを意味しています。


【格言】
  「自分のアーキテクチャを知るべし」
  「単純に測定せよ」
  「様々な戦術を試すことです」
  「出来るだけ多くの変形を試してください」

  「 何も想定してはいけません」
  「自分の想定に疑問を持ち先入観を持たないことです」
  「想定を疑うことを忘れないように」


ほとんどのパイプラインはFIFO(First-In,First-Out)キューです。
その考え方はFIFOにジオメトリステージとラスタライザステージ用のジョブを並べて待たせられることです。つまりパイプラインの次のステージがその結果を受け取る準備ができていなくても1つのステージはその作業を続けられます。その代わりに次のステージの準備ができたときそれを処理できるように、その結果を保存します。このようなバッファ処理はパイプラインのバランス調整をならし小さなボトルネックを目立たせなくするのに役立ちます。
 しかしステージが飢餓状態(starved)やブロック状態(blocked)になることがあります。例えばアプリケーションステージがかなり時間のかかる計算を実行していてジオメトリステージとラスタライザステージの前のFIFOが空のときにステージは飢餓状態になります。この場合ジオメトリステージもラスタライザステージも何もすることがないので両方とも飢餓状態です。
 ラスタライザが巨大なポリゴンを書いているときにステージのブロックが発生します。その際ジオメトリステージはラスタライザへのFIFOキューをジョブで満たしてしまうことがあります。この時点でジオメトリステージはそれ以上FIFOへジョブを登録できなくなるのでブロック状態になります。
スポンサーサイト

comment

Secret

プロフィール

syarekoube

Author:syarekoube
しゃれこうべとあずいの2人によるブログです。
主にアクションゲーム制作について発表しています。
あと、数学の研究です。

カテゴリー
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
ブロとも申請フォーム

この人とブロともになる

ブログ内検索
RSSフィード
リンク