Windows Phone Performance Analysisは、ゲームの実行を高速化します。考えられる理由は?


7

私が作成していたXNAゲームは、私のWP7デバイスでゆっくり実行されていました。しかし、Windows Phone Performance Analysisでボトルネックを見つけるためにそれを開始したとき、ゲームは同じデバイスでスムーズに実行されました。

少し後で問題を見つけましたが、これは隣接チェック機能でした。機能を最適化しましたが、ゲームは正常に動作します。

パフォーマンス分析モードでゲームが魔法のようにスピードアップしたのはなぜですか?考えられる説明はありますか?

これは、Perf分析モードでは高速に実行されたコードですが、それ以外の場合は低速でした。タワーディフェンスゲームでのダメージ対処機能です。

 foreach (Target myTarget in _targets)
 {
        for (int x = -1; x <= 1; x++)
        {
                for (int y = -1; y <= 1; y++)
                {
                    if (x == 0 && y == 0) continue;
                    try
                    {
                        Tile adjacent = _tiles[(int)myTarget.CurrentTile.X + x, (int)myTarget.CurrentTile.Y + y];
                        if (adjacent.Tower != null)
                        {
                            DealDamage(myTarget, adjacent.Tower);
                        }
                    }
                    catch
                    {
                    }
                }
            }
 }

各ターゲットではなく、各タワーの損傷をチェックすることで、後で最適化しました。


私には役立つ知識がありませんが、修正の前後にコードを追加すると他の人を助けることができるでしょう。
George Duckett

明確にするために、Perf Analysisモードで実行した場合、同じコードは一貫して高速に実行されました。私はこれが起こった理由を理解していません。後でコードを最適化したという事実は関係ありません。
ApoorvaJ 2012

1
無関係ではないかもしれませんが、変更したコードは分析ごとモードでは高速で、通常ではないようです。多分それを分離することができます。そのため、前後に投稿した場合、違いはパフォーマンス分析モードのほうが(何らかの理由で)優れている可能性があります。
ジョージデュケット

@GeorgeDuckett:有効なポイント。コードを追加しています。
ApoorvaJ 2012

2
おそらくキャッシュの問題です。おそらく、パフォーマンスはこのコードと同じ変数を読み取りますが、キャッシュメカニズムをトリガーするため、マップのデータは常にメモリ上にあります。
Tei

回答:


1

私の推測では、ネストされている可能性のある大きなネストされたループの反復ごとのtry / catchオーバーヘッドがパフォーマンスを低下させ、分析ツールが例外ハンドラのオーバーヘッドに何らかの影響を与えたと考えられます。プロファイラーなしで、例外処理を削除して通常どおり実行することで、簡単にテストできます。

タイトなループの内側でtry / catchをしたくありません。条件付きチェックを介してループ内で例外を生成する可能性のあるものをすべて考慮するか、少なくともループ全体をtry / catchすることを確認することをお勧めします。


試してみますが、この動作にはキャッシングが関係しているのではないかと思います。
ApoorvaJ

0

私はツール自体に精通しておらず、コンパイラの最適化の専門家でもありませんが、その理由は次のとおりです。

Tile adjacent = _tiles[(int)myTarget.CurrentTile.X + x, (int)myTarget.CurrentTile.Y + y];

ここで発生する可能性があるのは、Tile隣接するものがスタックに作成され、右側のタイルからコピーされた値が含まれている_tiles[]ことです(C ++で参照になるものを使用しておらず、C#に存在するかどうかわかりません)。したがって、Tileオブジェクトを継続的に作成および破棄し、さらに、2つの大きなネストされたforループ内にあります。スタック上にありますが、これは間違いなく速度に影響を与える可能性があります。おそらく起こったのは、Perf Analysisモードがこのシナリオを認識しTile、ネストされたループの外側でオブジェクトを事前に割り当て、関数を通じてそれを使い続け、作成/破棄のオーバーヘッドを回避したことです。


私はこの問題を早い段階で認識し、修正しました。これにより、パフォーマンスが大幅に向上することも、パフォーマンス分析モードでの魔法のスピードアップが変更されることもありませんでした。
ApoorvaJ 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.