C#中更快的矩阵乘法

时间:2010-12-29 10:24:34

标签: c# matrix matrix-multiplication

我有一个涉及矩阵的小型c#项目。我正在处理大量数据,将其分成n长度的块,将chucks作为向量处理,然后乘以Vandermonde **矩阵。问题是,根据条件,卡盘的尺寸和相应的Vandermonde **矩阵可以变化。我有一个易于阅读的通用解决方案,但速度太慢了:

    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兆。

(请注意“mod”正在以GF(2 ^ 8)为模运算我最喜欢的不可约多项式。)

我知道这可以快得多:毕竟,Vandermonde **矩阵大多是零。我应该能够制作一个例程,或找到一个例程,它可以获取我的矩阵并返回一个优化的方法,该方法将有效地将矢量乘以给定的矩阵,但速度更快。然后,当我给这个例程一个5x5 Vandermonde矩阵(单位矩阵)时,根本就没有算术可以执行,而原始数据只是被复制了。

**请注意:我使用术语“Vandermonde”,实际上是指一个Identity矩阵,其中附加了Vandermonde矩阵中的一些行(参见注释)。这个矩阵很棒,因为所有的零,并且因为如果你删除足够的行(你选择的)使它成为正方形,它是一个可逆矩阵。当然,我想使用相同的例程将这些反转矩阵中的任何一个转换为优化的指令系列。

如何让这种矩阵乘法更快?

谢谢!

(编辑以纠正我与Vandermonde矩阵的错误)

5 个答案:

答案 0 :(得分:3)

我见过使用Reflection.Emit的解决方案,我看过涉及TPL的解决方案。对于大多数情况,这里的真正答案是您希望通过P / Invoke使用现有的非托管库,例如英特尔MKL。或者,如果您使用GPU,则可以采用GPGPU方法,这样可以更快。

是的,SSE和多核处理是在CPU上执行此操作的最快方法。但我不建议你自己编写算法 - 而是去找那些已经存在的东西。最有可能的是,它最终会成为一个C ++库,可能还有一个C#包装器。

答案 1 :(得分:2)

也许您可以使用Reflection.Emit定义矩阵接口并在运行时构建实现。

IMatrix m = MatrixGenerator.CreateMatrix(data);

m.multiplyBy(...)

在这里,MatrixGenerator.CreateMatrix将创建一个定制的IMatrix实现,具有完整的循环展开,以及进一步的代码修剪(0个单元,身份等)。 MatrixGenerator.CreateMatrix可以缓存矩阵,以避免以后为同一组数据重新创建矩阵。

答案 2 :(得分:2)

您可以尝试使用:http://research.microsoft.com/en-us/projects/accelerator

描述: Accelerator是一个高级数据并行库,它使用GPU或多核CPU等并行处理器来加速执行。

您可以在C#/ F#

中使用它

答案 3 :(得分:1)

虽然它不会加快数学速度,但至少可以在.Net 4.0中使用Parallel.For的所有内核。 Microsoft link

答案 4 :(得分:0)

从数学角度来看

您可以查看特征空间,特征向量,特征值。我不确定你的申请是做什么的,如果有帮助的话。

你可以看一下LU Decomposition。

以上所有主题均可在维基百科上找到

从编程角度来看

您可以尝试使用SIMD,但它们专为4x4矩阵而设计,可以对3D空间进行均匀转换,主要用于计算机图形。

您可以为最常见的维度编写特殊算法。

Using SSE in c# is it possible?