优化数磨

时间:2014-03-30 13:31:14

标签: c# math optimization micro-optimization

长话短说,我必须在迭代过程中解决20..200块 - 三对角线性系统。系统尺寸为50..100块,每块50..100 x 50..100。我会在这里写下我对它的看法,并请你就我的想法分享你的意见,因为我可能在某种方面有误。

为了解决这些方程式,我使用Thomas算法的矩阵版本。它与标量一样,除了代替方程中的标量系数我有矩阵(即代替“a_i x_ {i-1} + b_i x_i + c_i x_ {i + 1} = f_i”我有“A_i X_ {i- 1} + B_i X_i + C_i X_ {i + 1} = F_i“,其中A_i,B_i,C_i - 矩阵; F_i和X_i是矢量。

这种算法的渐近复杂度为O(N * M ^ 3),其中N是块中整体矩阵的大小,M是每个块的大小。

现在我的瓶颈是倒置操作。在嵌套循环内部,我必须计算/很多/看起来像“(c_i - a_i * alpha_i)^ - 1”的反转,其中alpha_i是密集的MxM矩阵。我正在使用Gauss-Jordan算法,使用额外的内存(我将不得不在程序中使用)和O(M ^ 3)操作。

试图找到关于如何优化反演操作的信息,我发现只有关于AX = B系统'规范'的线程,即X = A ^ -1 B,建议使用LU分解代替它。遗憾的是,由于我的反演是Thomas算法的一部分,如果我求助于LU分解,我将不得不为M * NxM * N矩阵做这件事,这将增加解决线性系统的复杂性,增加N ^ 2到O(N ^ 3 * M ^ 3)。这个速度减慢了2500..10000,非常糟糕。

近似或迭代反演也超出了范围,因为具有精确反演的最轻微残差将累积得非常快并导致全局迭代过程爆炸。

我与Parallel.For()并行计算,分别解决每个20..200系统。

目前,为了解决20个这样的N系统,M = 50平均需要872ms(i7-3630QM,2.4Ghz,4个线程(8个超线程))。

最后,问题就来了。

  1. 我在这里写的是正确的吗?是否有一种算法可以显着加快计算速度?

  2. 在我的程序的数字磨床部分内部我只使用For循环(大多数都是恒定边界,异常是反演算法中的循环之一)双算术(+, - ,*, /)和标准数组([],[,],[,,])。如果我把这部分重写为不安全的话会有加速吗?或者作为C?中的库?

  3. 此类任务的C#开销是多少(双阵列磨削)? C编译器是否比C#'编译器'更好地优化了这样简单的代码?

  4. 在C#中优化numbergrinder时应该注意什么?是否适合这样的任务?

0 个答案:

没有答案