大型矩阵反演

时间:2012-06-27 15:40:57

标签: concurrency parallel-processing linear-algebra eigen matrix-inverse

我正在考虑采用大矩阵的逆矩阵,通常大小为1000 x 1000,但有时超过100000 x 100000(由于时间和内存,目前失败)。我知道正常的情绪是“不要反过来,找其他方法去做”,但目前这是不可能的。造成这种情况的原因是由于已经制作的软件需要使矩阵反转。 (注意:我正在研究如何改变这种情况,但这需要很长时间)

目前我们正在使用数值重新复制的LU分解方法,而我目前正在测试特征库。特征库似乎更稳定,速度更快,但我仍在测试阶段的准确性。我已经快速浏览了其他库,例如ATLAS和LAPACK,但尚未对这些库进行任何实质性测试。

似乎特征库不使用并发方法来计算逆(尽管对于逆分的LU分解部分),并且据我所知,ATLAS和LAPACK在此限制中是相似的。 (我目前正在使用openMP测试特征的速度差异而没有。)

第一个问题是任何人都可以解释如何通过并行化优化矩阵求逆。我发现了一篇关于矩阵求逆并行算法的文章here,但我不明白。似乎this文章讨论了另一种方法?我也不确定scaLAPACK或PETSc是否有用?

第二个问题,我阅读this使用GPU提高性能的文章,但我从来没有为GPU编写代码,所以不知道想要传达什么,但底部的图表看起来相当惊人。这怎么可能,以及如果真的如何,我该如何开始实现这样的事情。

我还发现了this文章,还没有时间阅读它来理解,但它似乎很有希望,因为内存是我们软件的当前问题。

有关这些文章或一般问题的任何信息都会有很大帮助。如果这个问题看起来含糊不清,我再次道歉,如果有必要,我会尽量扩大。

5 个答案:

答案 0 :(得分:8)

第一个问题是任何人都可以解释如何通过并行化来优化矩阵求逆。

我猜测这个以及线性代数中的相关主题是并行计算中研究最多的主题之一。如果你一直在寻找某个地方开始阅读,那么好的老Golub and Van Loan会有一个关于这个主题的章节。至于Scalapack和Petsc是否有用,肯定是前者,可能是后者。当然,他们都依赖于MPI,但这在这个领域是理所当然的。

第二个问题......

如果您拥有GPU,请使用GPU,并且可以将代码转换为GPU支持的编程模型。如果您从未编写过GPU编程并且可以访问商用类型的CPU集群,那么使用集群比使用新技术摔跤更快。

至于你提到的最后一篇文章,现在它在一个变化很快的领域已有10年历史了(试着找一篇关于使用GPU进行矩阵求逆的10年前的研究论文)。我不能评论它的卓越性或其他属性,但是你提到的问题规模在我看来完全在内核(使用旧术语)计算的现代集群的能力范围内。如果你的矩阵很大,它们也稀疏吗?

最后,我强烈支持您明确打算使用现有的现成代码,而不是尝试开发自己的代码。

答案 1 :(得分:5)

100000 x 100000是双精度80GB。您需要一个支持磁盘上内存映射矩阵的库。我不能推荐一个特定的库,我没有找到任何快速谷歌搜索。但是来自Numerical Recipes的代码肯定是不够的。

答案 2 :(得分:4)

关于第一个问题(如何平行计算反向):

我假设您通过对矩阵进行LU分解然后使用分解求解A * B = I来计算逆,其中A是您的原始矩阵,B是您求解的矩阵,我就是身份矩阵。那么B就是逆。

最后一步很容易平行化。沿着列划分您的单位矩阵。如果你有p个CPU并且你的矩阵是n-by-n,那么每个部分都有n / p列和n行。让我们调用部件I1,I2等。在每个CPU上,求解一个形式为A * B1 = I1的系统,这给你部分B1,B2等,你可以将它们组合成B形,这是反向的

答案 3 :(得分:2)

GPU上的LU分解速度比CPU快〜10倍。虽然现在正在发生变化,但GPU传统上是围绕单精度算法设计的,因此对于较旧的硬件,单精度算法通常比双精度算法快得多。此外,存储要求和性能将受到矩阵结构的极大影响。稀疏的100,000 x 100,000矩阵LU分解是一个需要解决的合理问题,并且不需要太多内存。

除非您想成为专家并花费大量时间进行硬件更新调整,否则我强烈建议您使用商业库。我建议CULA tools。它们具有稀疏和密集的GPU库,实际上它们free library提供SGETRF - 单精度(密集)LU分解例程。你必须支付他们的双精度库。

答案 4 :(得分:1)

我知道这是旧帖子 - 但实际上 - OpenCL(你根据你的显卡下载相关的一个)+ OpenMP + Vectorization(不是那个顺序)是要走的路。

无论如何 - 对我来说,我对矩阵的经验实际上与从系统内外复制双重双数组的开销以及在计算开始之前用0填充或初始化矩阵有关 - 特别是当我正在使用时为Excel使用创建.xll。

如果我要重新设置顶部优先级 -

  1. 尝试对代码进行矢量化(Visual Studio 2012和Intel C ++具有自动向量化 - 我不确定MinGW或GCC,但我认为编译器有标志来分析你的for循环以生成正确的汇编代码以供使用而不是用于保存数据的普通寄存器,以填充处理器的向量寄存器。我认为Excel正在这样做,因为当我在运行MINVERSE()时监视Excel的线程时,我注意到只使用了1个线程。 我不太了解汇编语言 - 所以我不知道如何手动矢量化......(还没有时间去学习这个但是太想要做到了!)
  2. 与OpenMP(omp pragma)或MPI或pthreads库(parallel_for)并行化 - 非常简单 - 但是......这就是捕获 - 我意识到如果你的矩阵类首先是完全单线程的 - 那么并行操作像mat multiply或inverse是可擦除的 - 因为初始化或复制到或只是访问非并行矩阵类,cuz并行化会降低速度。 但是...并行化有助于 - 如果你正在设计自己的矩阵类并且你并行化它的构造函数操作(用0等填充),那么你的LU(A ^ -1)= I的计算也会更快。 在数学上也可以直接优化LU分解,并优化前向后向替换特殊情况的身份。 (即不要浪费时间创建任何单位矩阵 - 分析你的for(row = col)和评估为1的函数,其余的为0。)
  3. 一旦它被并行化(在外层) - 需要逐个元素的矩阵运算可以被映射为由GPU(SSSSSS)计算 - 数百个处理器来计算元素 - 击败它!现在ATI的网站上提供了样本蒙特卡罗代码 - 使用ATI的OpenCL - 不用担心将代码移植到使用GeForce的东西 - 所有你要做的就是在那里重新编译。
  4. 虽然对于2和3 - 请记住,除非您正在处理F * K * G巨大的矩阵,否则会产生开销,但我看到100k ^ 2?哇...

    基因