The CPU Aspect of the D3D Pipeline

Download Report

Transcript The CPU Aspect of the D3D Pipeline

DirectX アプリケーションの
パフォーマンス チューニング
David Blythe (Architect)
Kev Gee (Software Design Engineer)
Microsoft Windows Gaming & Graphics Group
Microsoft Corporation
Agenda
D3D パイプラインの CPU 側面
正しい「エフェクト」の使い方
PIX
一般的な Windows パフォーマンス
D3D パイプラインの CPU 側面
実装の詳細と、それがパフォーマンス分析を
いかに邪魔するかを明らかにする
よく経験する混乱への対処
GPU パフォーマンス問題をよく理解するた
めの、関連する CPU パフォーマンス問題
CPU には、ある予算化も必要
理論的
最大値
30
フレーム / 秒
GPU
低スペック
GPU
高スペック
CPU
低スペック
CPU
高スペック
1G
ピクセル / 秒
100 M
三角形 / 秒
33 Mピクセル
/ フレーム
3 M三角形
/ フレーム
5G
ピクセル / 秒
500 M
三角形 / 秒
166 Mピクセル
/ フレーム
16 M三角形
/ フレーム
1 GHz
3 GHz
33 M
クロック
サイクル
/ フレーム
100 M
クロック
サイクル
/ フレーム
CPU 予算化に対する障害
CPU ボトルネックの識別
それが実際には何を意味しているのかを理解し
ない限り、 CPU プロファイルは不適切あるいは
誤解を招く
適切なコスト見積もりを導出
アプリケーション外のカスタム テクニックが必要
ブラック ボックスをより深く理解することが必要:
API とドライバ
Foo() がとる長さは ?
LARGE_INTEGER Start, End;
QueryPerformanceCounter( &Start );
Foo();
Foo(
vector<
i );
int >::push_back( i );
QueryPerformanceCounter( &End );
End -= Start;
コマンド バッファ
通常 D3D API は vector<>::push_back()
と類似
DrawPrimitive
SetRenderState
kernel-mode
driver
Command
Buffer
user-mode
SetRenderState
flush
SetRenderState
DrawPrimitive()
DrawPrimitive
SetRenderState
SetRenderState()
SetRenderState()
CPU コスト見積もりを測定する
カスタム手法
API とドライバ最適化の知識を使って、
不適切な測定を回避
手法の詳細は DirectX 9.0 SDK Update
Summer 2004 のヘルプ ドキュメント
「Direct3D 呼び出しの適切なプロファイリン
グ」
バッチとバッチ サイズ
バッチは Draw までの状態変更の集まり
バッチサイズはそのバッチが描画するプリミ
ティブの数
SetTexture( 0, pTexture1 );
SetStreamSource( 0, pVB1, 0, 32 );
SetRenderstate( D3DRS_CLIPPING, FALSE);
DrawPrimitive( D3DPT_TRIANGLELIST, 0, 25 );
Batch 1
DrawPrimitive( D3DPT_TRIANGLELIST, 100, 25 );
Batch2
SetRenderstate( D3DRS_CLIPPING, TRUE);
SetRenderState( D3DRS_LIGHTING, FALSE);
SetTexture( 0, pTexture2 );
SetStreamSource( 0, pVB2, 0, 32 );
SetVertexDeclaration( pDecl2 );
DrawPrimitive( D3DPT_TRIANGLELIST, 0, 256 );
Batch3
期待される結果
描画時間
Draw Time
The
time to render
1つのバッチを
one batch
レンダリングする
時間
Batch Size
バッチ サイズ The number of primitives in
1 DrawPrimitive
oneコマンド内のプリミティブの数
DrawPrimitive Command
結果の分析
描画時間
1つのバッチを
Draw Time
The time to render
レンダリングする
one batch
時間
傾き
Slope
GPU Cost
プリミティブあたりの
per-primitive
GPU コスト
CPU
CPUOverhead
CPU Cost
オーバーヘッド
per-batch
バッチあたりの
CPU コスト
Overhead
GPUGPU
オーバーヘッド
GPU Cost
バッチあたりの
GPU コスト
per-batch
バッチ サイズ
1 DrawPrimitive
Batch Size
The number of primitives in
one DrawPrimitive Command
コマンド内のプリミティブの数
DrawPrimitive の結果
6000
5000
4000
A
B
3000
2000
1000
0
1
9
17
25
33
41
49
57
65
73
81
89
97
概念的には次の呼び出しのコスト (CPU クロックサイクル) :
pD3DDevice->DrawPrimitive( …, BatchSize );
SetTexture の結果
6000
700
5000
4000
3500
3000
2300
A (DP+ST)
A (DP)
B (DP+ST)
B (DP)
2000
1000
0
1
9
17 25 33 41 49 57 65 73 81 89 97
pD3DDevice->SetTexture( … );
pD3DDevice->DrawPrimitive( …, BatchSize );
マイナス
pD3DDevice->DrawPrimitive( …, BatchSize );
GPU A SetVShaderConstF
8000
7000
6000
A (DP)
A (DP+SVSC+1C)
A (DP+SVSC+5C)
A (DP+SVSC+10C)
A (DP+SVSC+20C)
5000
4000
3000
2000
1000
0
1
11 21 31 41 51 61 71 81 91
pD3DDevice->SetVertexShaderConstantF( …, Constants );
pD3DDevice->DrawPrimitive( …, BatchSize );
マイナス
pD3DDevice->DrawPrimitive( …, BatchSize );
GPU B SetVShaderConstF
8000
7000
6000
B (DP)
B (DP+SVSC+1C)
B (DP+SVSC+5C)
B (DP+SVSC+10C)
B (DP+SVSC+20C)
5000
4000
3000
2000
1000
0
1
11 21 31 41 51 61 71 81 91
pD3DDevice->SetVertexShaderConstantF( …, Constants );
pD3DDevice->DrawPrimitive( …, BatchSize );
マイナス
pD3DDevice->DrawPrimitive( …, BatchSize );
SetVSConst の比較
8000
8000
7000
7000
6000
6000
A (DP)
A (DP+SVSC+1C)
A (DP+SVSC+5C)
A (DP+SVSC+10C)
A (DP+SVSC+20C)
5000
4000
3000
4000
3000
2000
2000
1000
1000
0
0
1
11 21 31 41 51 61 71 81 91
(A)
SVSC に 1100 クロックサイクル
+
130 クロックサイクル / 定数
B (DP)
B (DP+SVSC+1C)
B (DP+SVSC+5C)
B (DP+SVSC+10C)
B (DP+SVSC+20C)
5000
1
11 21 31 41 51 61 71 81 91
(B)
SVSC に 2100 クロックサイクル
+
100 クロックサイクル / 定数
ステート変更は主に CPU の制限
ステート変更の GPU コストは CPU コストの
ごく一部となりがち
ステート変更は 、CPU サイクルの消費に
よって、GPU を最適化していると考えられる
ステート変更を避ければ、CPU 時間の削減
に役立つ
もちろん、いくつかの例外がある
GPU A SetPShaderConstF
30000
25000
20000
A (DP)
A (DP+SPSC+1C)
A (DP+SPSC+2C)
A (DP+SPSC+4C)
A (DP+SPSC+8C)
15000
10000
5000
0
1
11 21 31 41 51 61 71 81 91
pD3DDevice->SetPixelShaderConstantF( …, Constants );
pD3DDevice->DrawPrimitive( …, BatchSize );
マイナス
pD3DDevice->DrawPrimitive( …, BatchSize );
GPU B SetPShaderConstF
30000
25000
20000
B (DP)
B (DP+SPSC+1C)
B (DP+SPSC+2C)
B (DP+SPSC+4C)
B (DP+SPSC+8C)
15000
10000
5000
0
1
11 21 31 41 51 61 71 81 91
pD3DDevice->SetPixelShaderConstantF( …, Constants );
pD3DDevice->DrawPrimitive( …, BatchSize );
マイナス
pD3DDevice->DrawPrimitive( …, BatchSize );
SetPSConst の比較
30000
30000
25000
25000
20000
A (DP)
A (DP+SPSC+1C)
A (DP+SPSC+2C)
A (DP+SPSC+4C)
A (DP+SPSC+8C)
15000
10000
20000
15000
10000
5000
5000
0
0
1
11 21 31 41 51 61 71 81 91
(A)
SPSC に 8600 クロックサイクル
+
2300 クロックサイクル / 定数
B (DP)
B (DP+SPSC+1C)
B (DP+SPSC+2C)
B (DP+SPSC+4C)
B (DP+SPSC+8C)
1
11 21 31 41 51 61 71 81 91
(B)
SPSC に 1000 クロックサイクル
+
250 クロックサイクル / 定数
前進
CPU オーバーヘッドの理解は、業界における大き
な障害
ハードウェア ベンダーと共に仕事をして同じ理解を
David Blythe が後で詳細を説明
今 CPU 負荷を減らす方法は ?
LOD エンジンに必ず CPU 作業もスケール
バックさせるようにする
利用可能なもの以上に高速な CPU を必要
とするレンダリング アルゴリズムを避ける
ジオメトリとテクスチャと (おそらく) シェーダを
融合する方法を見つける
「金のかなづち」的パフォーマンス アドバイス
を疑うこと
VidMem インデックス バッファをエ
ミュレーションする DirectX 8 部分
SetStreamSource
Driver B
12000
Render Time (CPU Cycles)
11000
10000
9000
8000
DRAWINDEXEDPRIMITIVE
7000
TOGGLE STREAMSOURCE
6000
5000
REDUNDANT
STREAMSOURCE
4000
3000
2000
1000
0
1
11
21
31
41
51
61
71
Batch Size (Primitives)
81
91
まとめ
測って、測って、測って…
潜在的な最適化を見つけたとき、関係するト
レードオフを理解してください
DirectX 9.0 SDK Update Summer 2004
ヘルプドキュメントの「Direct3D API 読み出
しの適切なプロファイリング」を読み通してく
ださい
Agenda
The CPU Aspect of the D3D Pipeline
正しいエフェクトの使い方
PIX
General Windows Performance
正しいエフェクトの使い方
エフェクトはどのように動作するか
エフェクトの効率的な使い方
ヒントとコツ
コア関数
Set* (SetFloat, SetMatrix…)
Begin
BeginPass
CommitChanges
EndPass
End
SDK Update 内の新しいメソッド
BeginPass
EndPass と一致するよう名前を変更した
CommitChanges
揮発セットを API で明白にする
詳細は後ほどお話します
EndPass
パスの終わりを識別する新しい関数
Set* メソッド
Set* メソッドは2つの事を行う:
入力データをハードウェアと親和性の高いフォー
マットに変換
パスの中間にある場合には、変更必要リストに
項目を追加する
Begin
Begin
ステートを保存
ステート保存レベルをユーザーが指定
完全ステート
シェーダのみ
サンプラのみ
パス用のその他の設定
ステートを格納しない場合には、
ほとんど何もしない
BeginPass
負荷の高い関数の1つ
Pass で指定された全ステートを適用
パス内で全ステートを明示的にリスト
全シェーダ定数を参照
頂点シェーダ / ピクセル シェーダの定数テーブルを
使って、どの定数レジスタを更新するかを決定
ピクセル シェーダが参照する全サンプラ
定数テーブルを使って使用サンプラを見つける
次に、サンプラが指定したステートを適用
揮発変数 Set* 呼び出し
DirectX 9 SDK と Summer Update 2003
SDK における API の振る舞い
Pass と End 間で発生した全ての Set 呼び
出しについて
その変数セットが影響を与えるステートを
デバイスに直接送る
セットの値は将来の Pass 呼び出しでも
思い出せる
CommitChanges
SDK Summer Update 2004 における API
の振る舞い
全 Set 呼び出しをキャッシュする
Set が BeginPass と EndPass 間で呼び
出されたとき
その更新をリストに置き、次の
CommitChanges 呼び出し時に適用
CommitChanges が呼び出されたときだけ、
デバイス ステートを更新
なぜ API を変更したのか ?
古い API には主に2つの不利な点があった
ほとんどの人々がそれを知らない
揮発 Set と Pass 呼び出しの両方を行っているため、
全ステートを2回設定している不注意な開発者を助け
るため
式とプリシェーダ
各変数が揮発 Set で設定されたとき、複数の変数を
持つ式は全て再計算が必要になる
i.e. mul (mWorld, mView)
【両方を設定した後で更新ないと、2度行う必要がある】
CommitChanges
デバイス ステートを適用し式を実行する唯一
のメソッド
BeginPass を除いて
最後の CommitChanges / BeginPass 以
降に、Set* 呼び出しの影響を受けたデバイス
ステートだけを更新する
変更がなければ負荷はない
ステート更新がなければ、単に戻るだけ
必要がなければ、必ずしも呼び出す必要はない
しかし不確かなら、逆を行ってはならない
EndPass
現在のパスの終了を識別
軽い関数
効率的なエフェクトの使用
レンダリングするマテリアル毎に一対の
Begin/BeginPass だけを呼び出す
エフェクトによるソートが必要
異なるデータ シナリオ
全て動的データ
ほとんどが静的
異なるエフェクト / シェーダの使い方でも動作
ループの例
// 注: 単純化のために、単一パスのエフェクトが、
//
まだエフェクトにはない共通のデータを
//
全てのオブジェクト用に、ここで設定していると仮定する
pEffect->Begin(…)
pEffect->BeginPass(0)
foreach object
{
// 現在の Draw 呼び出し用のインスタンスデータを設定
pEffect->Commitchanges()
// オブジェクトを描画する Draw を呼び出す
}
pEffect->EndPass()
pEffect->End()
シェーダによるグループ化
シェーダ配列を使っている場合にのみ必要
配列を使っていなければ、エフェクトによるソート
が【シェーダ】によるソートも含んでいる
変数を使って現在のシェーダを選択するとき
まず、エフェクトで draw 呼び出しをソート
次に、変数の変更によってソート
シェーダ インデックスの変更には、
BeginPass の呼び出しが必要
それ以外の役立つ情報
プリシェーダ (念のため)
シェーダ変数
プリシェーダ
プリシェーダは、ピクセル シェーダや頂点
シェーダから抽出した、実行時に変化しない
コード
mWorldView = mul(mWorld, mView)
Preshader の例
float4 main(float4 vDiffuse : COLOR0) :
COLOR0
{
return MaterialEmissive
+ MaterialAmbient * WorldAmbient
+ MaterialDiffuse * LightDiffuse *
vDiffuse ;
}
// ピクセル シェーダでは一般的ではないが、
// 頂点シェーダ内で同様のコードが見られる
生成したコード
//プリシェーダ
mul r0, c3, c4
add c1, r0, c2
mul c0, c0, c1
// 3 命令
ps_2_0
dcl v0
mov r0, c0
mad r0, r0, v0,
c1
mov oC0, r0
// 3 命令
// プリシェーダなし
ps_2_0
dcl v0
mov r0, c3
mov r1, c4
mad r1, r0, r1, c2
mov r0, c0
mul r0, r0, c1
mad r0, r0, v0, r1
mov oC0, r0
// 7 命令
プリシェーダ
プリシェーダを利用しないと決めたとしても
プリシェーダを使ったコンパイル後の出力
を見ると、アプリケーションで実行可能な実
行時に一定の式を、そのシェーダが持つか
どうかが分かる
共有変数
DirectX 9.0 SDK と Summer Update 2003
繰り返し設定しない変数についてのみ
共有を使うべき
共有するエフェクト間の従属性チェックに
オーバーヘッド
DirectX Summer Update 2004
繰り返し設定する変数でも、繰り返し設定しない
変数でも共有が使える
従属性維持のメソッド内で変更を行い、
オーバーヘッドを最小化
Agenda
D3D パイプラインの CPU 側面
正しいエフェクトの使い方
PIX を使ったグラフィックス パフォーマンスの
調査
一般的な Windows のパフォーマンス
PIX を使ったグラフィックス
パフォーマンスの調査
概要
プロファイリングのための必要条件
PIX for Windows
概要
発見した主な問題は、グラフィックス API や GPU
の使い方とは無関係
主なものは I/O
リソース、VMM、テクスチャ スラッシュのロード
いくつかは API に関連している
悪いフラグ、不正な選択、前提
残りが、「本当に」グラフィックスの問題
ドライバ パフォーマンス
バグ
使う際の前提
アルゴリズムが非効率的
概要
Direct3D アプリのプロファイルは難しい
GPU
CPU
ユーザーからカーネル
アプリ
Direct3D
ランタイム
コマンド
バッファ
ドライバ
ビデオ
カード
カーネルからユーザー
RAM
RAM
HDD
VMM
概要
CPU プロファイラはこの絵の一部だけしか
与えてくれない
GPU
CPU
ユーザーからカーネル
アプリ
Direct3D
ランタイム
コマンド
バッファ
ドライバ
ビデオ
カード
カーネルからユーザー
RAM
RAM
HDD
VMM
概要
GPU プロファイラは別の部分を与えてくれる
GPU
CPU
ユーザーからカーネル
アプリ
Direct3D
ランタイム
コマンド
バッファ
ドライバ
ビデオ
カード
カーネルからユーザー
RAM
RAM
HDD
VMM
概要
PIX for Windows は、プラグイン + OS カウンタ +
インストゥルメント Direct3D に効き、全ての絵を確認
GPU
CPU
ユーザーからカーネル
アプリ
Direct3D
ランタイム
コマンド
バッファ
ドライバ
ビデオ
カード
カーネルからユーザー
RAM
RAM
HDD
VMM
パフォーマンス最適化ガイドライン
プロファイラの結果を使って、努力の手引きと
する
違いが出るはずの領域の最適化にだけ時間を使
う
本当に複雑なコード部分がプロファイル上に登録されて
いないとしたら、その最適化は時間の有効な使い方で
はない
繰り返しプロファイルする
開発者によっては、パフォーマンスの退行を確認
するために、毎日のビルドで実行する
複数ハードウェア構成でプロファイルする
もちろん、これを考慮しない開発者もいる…
用語
CPU サンプリング プロファイラ
一定間隔で起動し実行中の関数を記録
記録した関数が自分のプロセスであることを保証しない
各関数が使用する割合(%)が得られる
最小のオーバーヘッド
ほとんどの時間でアイドルのまま
既存コードを修正せずに動作
用語
CPU インストゥルメント プロファイラ
次のように、測定する各領域に開始と停止の区
切りが必要
アプリケーション内に編集
コード エントリ ポイントを捕獲
測定中の各領域について適切な時間的結果
大きなオーバーヘッドを持つ場合がある
プロファイル コストが絶対時間に影響を与える
プロファイルの必要条件
いつ成功したかを決定するために、
何がほしいのかが分かっていること
グラフィックス パフォーマンスをフレーム予算の
割合(%)として決定
既知のシナリオのバリエーションとして、
パフォーマンス ゴールを設定
最低要件と推奨要件で決まることが多い
例えば、<n> アニメーション オブジェクト、
<m> 静的オブジェクト
= 20fps on 733PIII, 128Mb RAM
プロファイルの必要条件
決定論的な振る舞い
真の乱数を取り除く
既知の繰り返しキーを持つ擬似乱数発生器を使う
時間は物理時間ではない
グラフィックス パイプライン以外にも影響
AI、物理、衝突、可視スキーム、ゲームコードなど
最適化したビルド…
コンパイラによるリリース ビルドだけではなく
OutputDebugString() などの「テスト」コードを全て取り除く
プロファイルの必要条件
DirectX の考慮
最初に Direct3D デバッグ ランタイムを使って、ワーニン
グもエラーもないことを確認
Debug Output Level スライダを大きくする
Maximum Validation ボックスをチェック
最新のランタイムを使う…
次に、実際にプロファイを行うとき
リテール ビットで実行していることを確認
Direct3D だけではなく、全てリテール ビット
リフレッシュレートと同期させない
D3DPRESENT_INTERVAL_IMMEDIATE を使う
D3DQUERYTYPE_EVENT 結果の使用法をチェック
Pix for Windows
フレーム ベースのパフォーマンス プロファイラ
コード傍受によるインストゥルメント
プロファイル
ソースコードは不要
リテール コードで動作
アプリケーションを無効に設定しない限り
分析と取得の負荷によってオーバーヘッドは
変化
FPS のみ、完全マシン記録
現在のところ、マルチフレーム、単一フレームの
深い分析は開発中…
デモ
デモ
サポート
オペレーティング システム
Windows XP
Direct3D 9
将来のオペレーティング システムと
Direct3D バージョンは将来のバージョンで
サポート
将来の機能
D3DX を含む、より多くのフレーム統計とカウンタ
たとえば、フレームあたりのエフェクトの数
マルチフレーム シーンの記録
記録したシーンの分析
「悪い」Direct3D の使い方の検出とレポート
オブジェクトの追跡
Direct3D オブジェクト / 開放を追跡し、任意のフレームについて
オブジェクト ツリーを示す
リモート セッション
それ以外には ?
優先度付けを手伝ってください…
Agenda
D3D パイプラインの CPU 側面
正しいエフェクトの使い方
PIX for Windows
一般的なパフォーマンスのヒント
グラフィックス パフォーマンスのボトルネック
アプリ実行
フレーム
バッファ
BPPを変更
FPS
が変化?
Yes
フレーム
バッファ
スループットの
制限
No
テクスチャ
サイズを変更
FPS
が変化?
Yes
テクスチャの
制限
Yes
No
フレーム
バッファ
解像度を変更
FPS
が変化?
Yes
ピクセルシェーダ
命令の数を
変更
FPS
が変化?
No
No
頂点命令を
変更
FPS
が変化?
Yes
頂点
シェーダの
制限
No
頂点フォーマット
サイズ/AGP
レートを変更
FPS
が変化?
Yes
AGPの
制限
No
CPUの
制限
ピクセル
シェーダの
制限
フィル
レートの
制限
グラフィックス パフォーマンスのボトルネック
ロック ステップでの CPU / GPU
悪意なしで並列化を殺すベストな方法は ?
何も考えずにリソースをロックすること
リソースが使用中なのでアプリ
ケーションは待ちを強制される
アプリ
ランタイム / ドライバ
GPU
リソースの
ロック開始
データ
データの再フォーマット
/ GPU への転送
GPU でリソースを使用
リソースの
ロックが返る
一般的なグラフィックス パフォーマンスのヒント
インデックス化した三角形リストを使う
座標計算と照明計算の前後でキャッシュを十分に利用する
最善の方法 !
使う順番に頂点を並べ替える
D3DXOptimize*() と D3DXWeldVertices() ルーチンを使
う
キャッシュの使用を最大に !
バッチを考慮する:
DrawPrim 呼び出しあたり理にかなった数の頂点を使う
最善のバッチを得るために、CPU に過度に負荷をかけてはいけない
頂点シェーダを使ってインスタンス化したジオメトリをバッチ
Z プレパスを考慮する
一般的なグラフィックス パフォーマンスのヒント
オブジェクトを前から後ろにソート
マテリアル / エフェクトとレンダーステート単
位でバッチをソート
柔軟性のある設計
たとえば、シーングラフを使えば、
レンダリング時にマテリアルやモデルなどによる
異なるソート アルゴリズムを容易に実験できる
CPU / GPU へのブロックを取り除く
I/O 処理についてストール待ちをしない
コストを分割払いする、バックグラウンド読み込
みをしたデフォルト モデル・マテリアル・テクス
チャを使って、ユーザーからそのコストを隠す
一般的なパフォーマンスのヒント
コストを分割払い
妥当なレベルにフレームあたりの、事前に計算した時間
か最低値のいずれかで、リソースを作成 / 開放
コストを隠す
既に述べたように、リソースがすぐには利用できない場
合に、フォールバックするデフォルト オブジェクトを持つ
全てを同じスレッドに配置してはならない
しかし、全てを別のスレッドに配置してはならない !
一般的なパフォーマンスのヒント
Windows と共存、Windows の逆は避ける
Windows XP は完全に過半数のゲームプラット
フォーム
XP 用に設計し、Windows 9x にフォールバック
ANSI ではなく Unicode、FAX32 ではなく NTFS、など
共有メモリ、Virtual* 関数など
Windows パフォーマンス カウンタを理解する
PIX for Windows を使って独自のサブセットを定義
コンソールを越える(理にかなった)追加メモリーを
利用する
再計算ではなく事前計算
OutputDebugString() は両側ソート
一般的なパフォーマンスのヒント
最も強力なパフォーマンス ツールの1つはコンパイ
ラ
最新バージョンを使う
ネイティブ コンパイラにある最適化はバージョンごとに改善
コンパイラ フラグを知り、親しむ
ターゲットとする CPU 用にコンパイル
PIII+ に全て移行すべき
Visual Studio® .Net 2003 上で FP 用に生成した自動 SSE
コードを取得できる
ワーニング レベルを上げる
コード生成関連、64 ビット ワーニングなど
アラインメント問題を考慮
ここで VTune は非常に役立つ
一般的なパフォーマンスのヒント
大きなファイルをロードするとき NTFS は非常に高速
FAT32を超えるセキュリティが追加されているので、
より多くのリソースが必要
FAT32でもウィルス チェッカが広く使われているが、
それはコストを増やす
同じファイルを繰り返し開け閉めすることは避ける
あるいは、多くのファイルをまばらに
理想的には、線形データ アクセス パターンを持つ
パックしたデータファイルを使い、
ファイルをオープンし続ける
一般的なパフォーマンスのヒント
使用法パターンについてシステム情報を
与える
CreateFile( ) 呼び出し内で
FILE_SCAN_SEQUENTIAL フラグを使う
始めから終わりまでファイルを全て読み込むとき、
アクセスを最適化
OS はアクセスの先読み込みを行う
理想的は、要求する順序にデータを並べる
特に CD や DVD から読み込むとき
ゲームが基本的に線形な性質を持つとき、
できるだけデータを複製して、
連続読み込みパターンを保持する
一般的なパフォーマンスのヒント
LoadLibrary() を使ってコントロール DLL を
ロード
DLL をいつロードするかの制御をプログラマに
与える
C 関数ポインタ構文はコードが同じに見えること
を意味する
別の方法として、「遅延読み込み」リンカ設定
を使う
アプリケーションの開始をよりすばやくできる
一般的なパフォーマンスのヒント
DisableThreadLibraryCalls() を呼び出す
通常、プロセス内の新しいスレッドそれぞれにつ
いて、DLL_THREAD_ATTACH を付けて
DLLMain が呼び出される
ほとんどの DLL はこの情報を使わない
この場合、DLLMain から真っ直ぐ返るだけだが、
その時までにコードが既にページインしてしまう
DisableThreadLibraryCalls() を呼び出すと、
最初の段階でシステムによるその呼び出しを回
避できる
一般的なパフォーマンスのヒント
DLL グローバル変数は一度だけ静的に
初期化
定数変数は const として宣言
コンパイラはその変数をまったく無視する
読み取り専用セクションにそれを配置する
ページの読み書きは純正読み書きデータと
より密接に結びついているので、
ページング特性が改善
(使う場合は) どの種の例外処理を使うかを
コンパイラに教える
一般的なパフォーマンスのヒント
メモリはランダム アクセスではないかもしれな
い
例えば、DWARD で2メガバイトのページ メモリを
書き込む (4k ページ)
最善の場合 = 512 ページ フォルト、連続書き込み
最悪の場合 = ˜1,000,000 ページ フォルト (1024^2 )
各ページ フォルトは 10 ミリ秒かかるとする
最善の場合 = 5 秒 (512 * 10ms)
最悪の場合 = 2.75 時間 (1,000,000 * 10ms =
10,000 秒)
お願いしたいこと
定期的な日常作業でプロファイルしてください
感謝祭の数週間前にみんなが頼みに来るので
なければ、私たちは援助できます
DirectX ベータに参加していないのであれば、
以下にメールしてください !
[email protected]
フィードバックや提案などは
[email protected]
ご質問は ?
?
?
?
?
?
?
?
?
?
?
?
お知らせ
SDK & 日本語ドキュメント送付申し込み
出口の箱に名刺を入れてください
DirectX Graphics Meeting (9/8)
開発者の方と WGF の仕様などに対する
フィードバックを個別に1時間づつ議論
講演終了後、川西にお問い合わせください
© 2004 Microsoft Corporation. All rights reserved.
This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.