10

配列内の要素に対して多くの演算を実行するときにパフォーマンスを最適化するために、C# で 2D 配列を格納する最良の方法はどれですか?

大規模な (約 1.5G) 配列があり、たとえば、要素ごとに互いに乗算したいと考えています。パフォーマンスは重要です。これが行われるコンテキストは c# にあります。配列を保存して反復処理するスマートな方法はありますか? これらの部分をアンマネージ C++ で書くことはできますか?これによって本当にパフォーマンスが向上しますか? 配列は、C# プログラムの残りの部分からアクセスできる必要があります。

現在 (c では​​)、配列は単一の長いベクトルとして格納されます。配列内の各要素に対して計算を実行し、古い値を上書きします。計算は通常、ベクトル内の各要素に対して一意です。

タイミング実験では、データを C# の配列として格納して反復処理すると、2D 配列として格納するよりも時間がかかることが示されています。データを処理するためのさらに良い方法があれば知りたいです。実行される特定の算術は、質問には関係ありません。

4

4 に答える 4

8

アンナ、

これは、従来の科学的プログラミング言語 (fortran、C++) と c# のパフォーマンスの違いについて説明している素晴らしいページです。

http://msdn.microsoft.com/en-us/magazine/cc163995.aspx

C# の記事によると、矩形配列 (2d) を使用すると、非常に優れたパフォーマンスを発揮する可能性があります。これは、ギザギザ配列 (配列の配列) と長方形配列 (多次元) 配列のパフォーマンスの違いを示すグラフです。

代替テキスト http://i.msdn.microsoft.com/cc163995.fig08.gif

自分で実験して、VS 2008 のパフォーマンス分析を使用して比較することをお勧めします。

C# の使用が「十分に高速」である場合、アプリケーションの保守ははるかに簡単になります。

幸運を!

于 2008-09-21T13:55:06.950 に答える
5

配列のパフォーマンスを最適化するには、インデックスが 0 未満の単一次元配列を使用していることを確認してください。

配列の要素にできるだけ早くアクセスするには、次のように安全でないポインターを使用できます。

int[] array = Enumerable.Range(0, 1000).ToArray();

int count = 0;
unsafe {
    fixed (int* pArray = array) {
        for (int i = 0; i < array.Length; i++) {
            count += *(pArray + i);
        }
    }
}

ドラットを編集!あなたが2D配列と言ったことに気づきませんでした。このトリックは多次元配列では機能しないため、どれだけ役立つかわかりません。ただし、配列インデックスに対して何らかの演算を実行することで、任意の配列を 1 次元配列に変換できます。配列のインデックス作成または配列の反復処理におけるパフォーマンスの低下を気にするかどうかによって異なります。

于 2008-09-21T13:46:42.727 に答える
2

F# をダウンロードし、ランタイム ライブラリの 1 つ (FSharp.PowerPack だと思います) を参照し、Microsoft.FSharp.Maths.Matrix を使用する場合。密行列または疎行列のどちらを使用しているかに基づいて、それ自体が最適化されます。

于 2008-09-21T14:03:12.157 に答える
0

行ごと、列ごと、またはその両方で行列を反復しますか? 常に近くの要素にアクセスしますか、それともマトリックスでランダム アクセスを行いますか。

アクセスに局所性があり、シーケンシャルにアクセスしていない場合 (行列の乗算などで一般的)、行列をよりキャッシュしやすい方法で格納することで、パフォーマンスに大きな違いを得ることができます。

これを行うための非常に簡単な方法は、小さなアクセス関数を記述して、行/列のインデックスをインデックスに変換し、1 次元マトリックスで作業することです。これは、キャッシュに適した方法です。

関数は、近くの座標を近くのインデックスにグループ化する必要があります。モートン順序は、2 のべき乗サイズで作業する場合に使用できます。非累乗サイズの場合、多くの場合、最下位 4 ビットのみをモートン順序にし、上位ビットには通常のインデックス演算を使用できます。座標からインデックスへの変換がコストのかかる操作のように見えても、大幅な高速化が得られます。

http://en.wikipedia.org/wiki/Z-order_(curve) <-- 申し訳ありませんが、ダッシュが含まれる URL が気に入らないのでリンクできません。カットアンドペーストする必要があります。

10倍以上のスピードアップは現実的です。ただし、マトリックスを処理するアルゴリズムによって異なります。

于 2008-09-21T14:37:18.940 に答える