locked
Performance Monitorの起動について RRS feed

  • 質問

  • こんにちは。質問ばかりですいません。

     

    先日、skinning sampleの配置が初めてできたので、

    win上とxbox360上とでパフォーマンスの差がどのくらいでるのか試してみました。

     

    サンプルを少し改造してfpsを計測・表示するようにし、

    AnimationPlayerのインスタンスを複数作ってListで持たせただけです。

     

    Code Snippet

                animationPlayers = new List();
              
                for (int i = 0; i < numChar; i++)
                {
                    AnimationPlayer player = new AnimationPlayer(skinningData);
                    player.StartClip(clip);
                    animationPlayers.Add(player);
                }

     

    Code Snippet

                // Render the skinned mesh.
                for (int i = 0; i < numChar; i++)
                {
                    foreach (ModelMesh mesh in currentModel.Meshes)
                    {
                        foreach (Effect effect in mesh.Effects)
                        {
                            effect.Parameters["Bones"].SetValue(animationPlayers[i].GetSkinTransforms());
                            effect.Parameters["View"].SetValue(view);
                            effect.Parameters["Projection"].SetValue(projection);
                        }

                        mesh.Draw();
                    }
                }

     

     

    結果は以下のようになりました。

     

    キャラ表示数  win   xbox360

    1        890     1843

    2                 715      1064

    3                  609      753

    4                 526       580

    5                 463       469

    6                  415        399

    20              130-160   123

    50                65           47

     

    とりあえずxboxの方では表示キャラの増加に対するFPSの落ち込みが激しいと感じましたので、

    もしかしてGCとかいう奴なのかなと思い、

    パフォーマンスモニタを使ってみようと思ったのですが起動しませんでした。

     

    1.xbox側で配置するときと同じようにGS Connectを起動

    2.performance monitor起動

    3.performance monitorの「Device」のプルダウンに

     xbox(VC#のDeviceCenterで追加したものを自動で認識?)があったのでそれを選択

    4.performance monitorの「Applicatoin」に「SkinningSample」と入力

    5.performance monitorの「Launch」を押す

     

    という手順を踏みましたが、

    結果はsystem.Timeout.Exceptionというエラーがでて起動できませんでした。

    試しに4.で「SkinningSample.exe」と入力してみましたがこれもダメでした。

     

     

    そこで質問なのですが、

    ・performance monitorの起動法はどこが間違っているでしょうか?

    ・xbox側のパフォーマンス低下はGCが原因と考えていいのでしょうか?

    ・performance monitorを使用することでGCの「発生回数」を確かめることはできそうなのですが、

    「発生箇所(ソースのどこに原因があるのか)」を特定することはできるのでしょうか?

     

     

    テスト環境は以下のとおりです。

    GS2.0

    WinXP sp3

    Athlon64 3200+ 2GHz

    メモリ1G

    Geforce7900GS

     

    よろしくお願いします。

    2008年12月7日 6:24

回答

  • Remote Perfromance Monitor(以下RPM)のApplicationには「アセンブリタイトル名」を指定します。これはXbox 360上でゲームライブラリ上で表示されている名前です。この名前はAssemblyInfo.cs(Propertiesの中)の中で以下のように指定されています。

    [assembly: AssemblyTitle("Skinning Sample")]

    Skinning Sampleの場合はSkinningとSampleの間にスペースがあるのでRPMの中で「Skinning Sample」と指定する必要があります。

    Skinning SampleではGCは発生しないのでGCはパフォーマンス問題にはなりません。

    残念ながら現状ではRPMを使って、どこでメモリアロケーションやボクシングが発生しているのかを特定する機能はありませんが、GC Heapの中でどのクラスがどれだけのメモリを確保しているかは調べることはできます。

    .Netではリリース、デバッグ時に生成するコードが違うのはもちろん、デバッガにアタッチしている時にも完全なリリース時とは違うコードを生成することに注意してください。ですから、パフォーマンスを測定するときはVisaul Studio上でF5ではなく、Ctrl+F5を押して実行するようにしてください。


    測定はしていませんが、このサンプルでボトルネックになりそうなのはボーンの計算部分だと思われます。UpdateWorldTransfomrsメソッド内で行列の計算をするのにm1 = m2 * m3のように最終的に値渡しの関数を呼んでいるので一回の計算で数百バイトのコピーが発生しているので、この部分を参照渡しのメソッドに変更するだけでも大分早くなると思います。また
    、通常は4x3の行列同士の計算で済むところを常に4x4の行列計算をしているので、このメソッド内で4x3の行列同士の計算をすると言う手もあります。

    もう一つボトルネックになりそうなのは、描画部分でひとつのモデル毎に様々な描画関係のステートを変更しているところです。例えばViewやProjectionの設定は1フレームに一回で良いので、それだけで50体描画時に行列設定を100回しているのが2回に減ります。また、mesh.Drawの中ではEffect.Begin/Endの他にも描画用のAPIを多数呼んでいるので、これはマテリアルバッチをすることで減らすことができます。

    マテリアルバッチについては以下のURLにある「XNA Frameworkのパフォーマンス」が参考になると思います。
    この中のモデルインスタンスの中でマテリアルバッチについて説明しています。
    http://msdn.microsoft.com/ja-jp/xna/cc723908.aspx
    2008年12月7日 13:58

すべての返信

  • Remote Perfromance Monitor(以下RPM)のApplicationには「アセンブリタイトル名」を指定します。これはXbox 360上でゲームライブラリ上で表示されている名前です。この名前はAssemblyInfo.cs(Propertiesの中)の中で以下のように指定されています。

    [assembly: AssemblyTitle("Skinning Sample")]

    Skinning Sampleの場合はSkinningとSampleの間にスペースがあるのでRPMの中で「Skinning Sample」と指定する必要があります。

    Skinning SampleではGCは発生しないのでGCはパフォーマンス問題にはなりません。

    残念ながら現状ではRPMを使って、どこでメモリアロケーションやボクシングが発生しているのかを特定する機能はありませんが、GC Heapの中でどのクラスがどれだけのメモリを確保しているかは調べることはできます。

    .Netではリリース、デバッグ時に生成するコードが違うのはもちろん、デバッガにアタッチしている時にも完全なリリース時とは違うコードを生成することに注意してください。ですから、パフォーマンスを測定するときはVisaul Studio上でF5ではなく、Ctrl+F5を押して実行するようにしてください。


    測定はしていませんが、このサンプルでボトルネックになりそうなのはボーンの計算部分だと思われます。UpdateWorldTransfomrsメソッド内で行列の計算をするのにm1 = m2 * m3のように最終的に値渡しの関数を呼んでいるので一回の計算で数百バイトのコピーが発生しているので、この部分を参照渡しのメソッドに変更するだけでも大分早くなると思います。また
    、通常は4x3の行列同士の計算で済むところを常に4x4の行列計算をしているので、このメソッド内で4x3の行列同士の計算をすると言う手もあります。

    もう一つボトルネックになりそうなのは、描画部分でひとつのモデル毎に様々な描画関係のステートを変更しているところです。例えばViewやProjectionの設定は1フレームに一回で良いので、それだけで50体描画時に行列設定を100回しているのが2回に減ります。また、mesh.Drawの中ではEffect.Begin/Endの他にも描画用のAPIを多数呼んでいるので、これはマテリアルバッチをすることで減らすことができます。

    マテリアルバッチについては以下のURLにある「XNA Frameworkのパフォーマンス」が参考になると思います。
    この中のモデルインスタンスの中でマテリアルバッチについて説明しています。
    http://msdn.microsoft.com/ja-jp/xna/cc723908.aspx
    2008年12月7日 13:58
  • マテリアルバッチなどのパフォーマンス改善法など大変参考になりました。

    実際試してみたら、少ない手数でそこそこfpsが改善しました。

     

    performance monitorにつきましては、「Skinning Sample」と正しい名前を入れても

    なぜかやはり2.0のものは接続できませんでした。

    仕方がないのでGS3.0をインストールしてそちらの新しい方を使ってみたところ起動することができました。

    2.0の方が使えなかった原因は良くわからないのですが、

    とりあえず3.0の方が使えたのでこちらを使用していこうと思います。

    ありがとうございました。

    2008年12月7日 22:34