C# での計算オーバーヘッド - ゲッター/セッターの使用と配列の直接変更とキャスト速度

StackOverflow https://stackoverflow.com/questions/3018536

質問

長々と書くつもりでしたが、ここで要約します。

XNA を介して NES のグラフィックの昔ながらのスタイルをエミュレートしようとしています。ただし、フレームあたり 65K ピクセルを変更しようとしているため、FPS が遅くなります。65K ピクセルすべてをループして任意の色に設定すると、64FPS が得られます。どの色をどこに配置するかを調べるために作成したコードでは、1FPS が得られます。

私のオブジェクト指向コードのせいだと思います。

現在、ゲッター/セッターを含む約 6 つのクラスに分割しています。フレームごとに少なくとも 360K のゲッターを呼び出していると思いますが、これはかなりのオーバーヘッドだと思います。各クラスには、カスタム列挙型、int、Color、または Vector2D バイトを含む 1D 配列または 2D 配列のいずれか、またはその両方が含まれます。

すべてのクラスを 1 つに結合し、各配列の内容に直接アクセスしたらどうなるでしょうか?コードは乱雑に見え、オブジェクト指向コーディングの概念が無視されますが、速度ははるかに速くなる可能性があります。

また、配列内のデータの取得/設定の試行はブロック単位で行われるため、アクセス違反についても心配しません。たとえば、配列へのすべての書き込みは、配列からデータがアクセスされる前に行われます。


キャストに関しては、使用していると述べました カスタム列挙型、int、Color、Vector2D、バイト。 .net Framework、XNA、XBox、C# で使用およびアクセスするのに最も速いデータ型はどれですか?一定のキャストがここでの速度低下の原因である可能性があると思います。

また、データをどのインデックスに配置するかを計算するのではなく、事前に計算されたルックアップ テーブルを使用したので、フレームごとに定数の乗算、加算、減算、除算を使用する必要がありません。:)

役に立ちましたか?

解決

GDC 2008 には、XNA 開発者であれば読む価値のある素晴らしいプレゼンテーションがあります。それは呼ばれています XNA フレームワークのパフォーマンスを理解する.

現在のアーキテクチャについては、明確な答えを与えるほど十分に説明されていないため、おそらくタイトなループ内で不必要な「処理」を実行しすぎていると思われます。推測しなければならないとしたら、現在のメソッドがキャッシュをスラッシングしているため、データ レイアウトを修正する必要があると思います。

理想的なケースでは、可能な限り小さい、大きな配列が必要です。 値の型 (クラスではなく構造体)、データを線形に押し込む高度にインライン化されたループ。

(余談:何が速いのかについては、整数および浮動小数点の計算は非常に高速です。一般に、ルックアップ テーブルは使用しないでください。関数呼び出しは非常に高速です。大きな構造体を渡すときにそれをコピーする方が重要です。JIT は単純なゲッターとセッターをインライン化します。ただし、ブリッターのように、非常にタイトなループ内で他のものをインライン化するために JIT に依存すべきではありません。)

しかし - 最適化されていても - 現在のアーキテクチャは最悪です。あなたがやっていることは、最新の GPU の仕組みに反するものです。スプライトを GPU にロードして、シーンを合成させる必要があります。

スプライトをピクセル レベルで操作したい場合 (例:あなたが述べたようにパレットの交換)、その場合はピクセルシェーダーを使用する必要があります。360 (および PC) の CPU は高速ですが、このようなことを行うときは GPU のほうがはるかに高速です。

スプライト効果 XNA サンプルは、始めるのに適した場所です。

他のヒント

あなたは景気減速がどこにあるかを決定するためにあなたのコードをプロファイリングしましたか?あなたがあなたのアプリケーションを書き換える行く前に、あなたは部品を書き換える必要があり、少なくとも知っているはずます。

私は強くアクセサとデータ変換のオーバーヘッドが自明であると思われます。それはあなたのアルゴリズムは、不必要な仕事をして、彼らがキャッシュできると値を再計算し、あなたのオブジェクトのデザインを爆破せずに対応することができる他の事していることをより多くの可能性があります。

あなたは、各ピクセルか何かの色と、そのような指定されていますか?その場合は、私はあなたが実際にいくつかのより多くのアーキテクチャを考えるべきだと思います。物事をスピードアップスプライトを使用して起動します。

EDIT

さて、私はあなたのソリューションは、異なる色(数ピクセルのスプライト)とし、それらの再利用負荷いくつかのスプライト何ができるかと思います。これは、スプライトが既にメモリにロードされているように、各画素に異なる色を割り当てることよりも速く点まで同じスプライトにある

は、パフォーマンスの問題と同じように、あなたはかなり推測しようとするよりも、ボトルネックを特定するためのアプリケーションをプロファイリングする必要があります。私は真剣にゲッターとセッターがあなたの問題の根本にあることを疑います。コンパイラは、ほとんど常に機能のこれらの種類をインライン化。私はまた、あなたが数学に対して持っているもの興味があります。例えば、2つの整数を乗算すると、コンピュータが行うことができます最速のものの一つです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top