我需要更快地进行操作

问题描述 投票:0回答:3

我有一段代码从 stl 读取点,然后我必须对这个 stl 进行转换,应用转换矩阵并将结果写入其他 stl。我做了所有这些事情,但它太慢了,大约 5 分钟或更长时间。

我输入矩阵乘法的代码,它接收两个矩阵并进行乘法:

public double[,] MultiplyMatrix(double[,] A, double[,] B)
    {
        int rA = A.GetLength(0);
        int cA = A.GetLength(1);
        int rB = B.GetLength(0);
        int cB = B.GetLength(1);
        double temp = 0;
        double[,] kHasil = new double[rA, cB];
        if (cA != rB)
        {
            MessageBox.Show("matrix can't be multiplied !!");
        }
        else
        {
            for (int i = 0; i < rA; i++)
            {
                for (int j = 0; j < cB; j++)
                {
                    temp = 0;
                    for (int k = 0; k < cA; k++)
                    {
                        temp += A[i, k] * B[k, j];
                    }
                    kHasil[i, j] = temp;
                }
            }
            return kHasil;
        }
        return kHasil;
    }

我的问题是所有代码都太慢了,它必须从一个 stl 中读取,将所有点相乘并将结果写入其他 stl,这需要 5-10 分钟才能完成。我看到所有商业程序,如 cloudcompare,都在几秒钟内完成所有这些操作。

谁能告诉我怎样才能做得更快?有没有比我的代码更快的图书馆?

谢谢! :)

c# matrix time transformation
3个回答
1
投票

我在网上喜欢这个:

 double[] iRowA = A[i];
double[] iRowC = C[i];
for (int k = 0; k < N; k++) {
    double[] kRowB = B[k];
    double ikA = iRowA[k];
    for (int j = 0; j < N; j++) {
        iRowC[j] += ikA * kRowB[j];
    }
}

然后使用 Plinq

 var source = Enumerable.Range(0, N);
var pquery = from num in source.AsParallel()
             select num;
pquery.ForAll((e) => Popt(A, B, C, e));

Popt 是我们的方法名称,采用 3 个锯齿状数组 (C = A * B) 和要计算的行 (e)。这有多快:

 1.Name   Milliseconds2.Popt       187

来源是:Daniweb

这比我们的原始代码快 12 倍多!借助 PLINQ 的魔力,我们在此示例中创建了 500 个线程,而不必管理其中一个,一切都为您处理。


0
投票

你有几个选择:

  1. 用锯齿状数组(如

    double[][] A
    )重写代码,它应该使速度提高约 2 倍。

  2. 用矩阵乘法代码编写非托管C/C++ DLL。

  3. 使用在引擎盖下具有本机 BLAS 实现的第三方数学库。我建议Math.NET Numerics,它可以switched使用Intel MKL,它正在快速吸烟。

或许,第三种选择是最好的


0
投票

仅作记录:CloudCompare 不是商业产品。这是一个免费的开源项目。而且没有“庞大的开发人员团队”(实际上只有少数人在空闲时间这样做)。

这是我们最大的秘密:我们使用纯 C++ 代码;)。而且我们很少使用多线程,但对于非常冗长的过程(你必须考虑线程管理和处理时间开销)。

以下是代码中称为多次加载的部分的一些“最佳实践”规则:

  • 避免任何动态内存分配
  • 尽可能少(远)调用函数
  • 始终在“if-then-else”分支中首先处理最可能的情况
  • 避免非常小的循环(如果 N = 2 或 3,则内联它们)
© www.soinside.com 2019 - 2024. All rights reserved.