10

行列を含む小さなc#プロジェクトがあります。大量のデータをn個の長さのチャンクに分割し、チャックをベクトルとして扱い、ファンデルモンド**行列を乗算することで処理しています。問題は、条件に応じて、チャックのサイズと対応するファンデルモンド**行列が変化する可能性があることです。私は読みやすい一般的な解決策を持っていますが、遅すぎます:

    public byte[] addBlockRedundancy(byte[] data) {
        if (data.Length!=numGood) D.error("Expecting data to be just "+numGood+" bytes long");

        aMatrix d=aMatrix.newColumnMatrix(this.mod, data);
        var r=vandermonde.multiplyBy(d);
        return r.ToByteArray();
    }//method

これは、私のi5 U470@1.33GHzで毎秒約1/4メガバイトを処理できます。行列の乗算を手動でインライン化することで、これを高速化できます。

        int o=0;
        int d=0;
        for (d=0; d<data.Length-numGood; d+=numGood) {
            for (int r=0; r<numGood+numRedundant; r++) {
                Byte value=0;
                for (int c=0; c<numGood; c++) {
                    value=mod.Add(value, mod.Multiply(vandermonde.get(r, c), data[d+c]));
                }//for
                output[r][o]=value;
            }//for
            o++;
        }//for

これは、1秒間に約1メガを処理できます。

(「mod」は、私のお気に入りの既約多項式を法としてGF(2 ^ 8)に対して演算を実行していることに注意してください。)

私はこれがはるかに速くなることを知っています:結局のところ、ファンデルモンド**行列はほとんどゼロです。行列を取得して、ベクトルに指定された行列を効果的に乗算する最適化されたメソッドを返すことができるルーチンを作成するか、ルーチンを見つけることができるはずですが、より高速です。次に、このルーチンに5x5のファンデルモンド行列(単位行列)を与えると、実行する演算がなく、元のデータがコピーされるだけです。

**注意:私が「ファンデルモンド」という用語を使用しているのは、実際には、ファンデルモンド行列のいくつかの行が追加された単位行列を意味します(コメントを参照)。この行列は、すべてゼロであるため素晴らしいものです。また、(選択した)行を十分に削除して正方形にすると、可逆行列になります。そしてもちろん、これと同じルーチンを使用して、これらの逆行列のいずれかを最適化された一連の命令に変換したいと思います。

この行列の乗算を高速化するにはどうすればよいですか?

ありがとう!

(ファンデルモンド行列の間違いを修正するために編集)

4

4 に答える 4

3

Reflection.Emitを使用して、マトリックス インターフェイスを定義し、実行時に実装を構築できるかもしれません。

IMatrix m = MatrixGenerator.CreateMatrix(data);

m.multiplyBy(...)

ここでMatrixGenerator.CreateMatrixは、完全なループ アンローリングとさらにコードのプルーニング (0 セル、ID など) を使用して、調整された IMatrix 実装を作成します。MatrixGenerator.CreateMatrix行列をキャッシュして、後で同じデータ セットに対して再作成しないようにすることができます。

于 2010-12-29T10:44:31.087 に答える
3

Reflection.Emit を使用したソリューションを見てきました。また、TPL を含むソリューションを見てきました。ここでの本当の答えは、ほとんどの場合、インテル® MKL などの既存のアンマネージライブラリーを P/Invoke 経由で使用することです。あるいは、GPU を使用している場合は、はるかに高速な GPGPU アプローチを使用できます。

はい、SSE とマルチコア処理を組み合わせることで、CPU でこれを実行する最速の方法が得られます。ただし、独自のアルゴリズムを作成することはお勧めしません。代わりに、既に存在するものを探してください。ほとんどの場合、C# ラッパーを含む C++ ライブラリになる可能性があります。

于 2010-12-29T11:47:38.397 に答える
1

計算を高速化するわけではありませんが、少なくともすべてのコアを .Net 4.0 の Parallel.For で使用できます。マイクロソフトのリンク

于 2010-12-29T16:49:02.427 に答える
0

数学の観点から

固有空間、固有ベクトル、固有値を見ることができます。あなたのアプリケーションが何をするのか、それが役立つかどうかはわかりません。

LU分解を見ることができます。

上記のトピックはすべてウィキペディアで見つけることができます

プログラミングの観点から

SIMD を試すこともできますが、それらは 4x4 行列が 3D 空間の均一な変換を行うように設計されており、主にコンピュータ グラフィックス用です。

最も一般的なディメンションに対して特別なアルゴリズムを作成できます。

C# で SSE を使用することは可能ですか?

于 2010-12-29T10:41:03.050 に答える