大矩阵反演



我正在考虑取一个大矩阵的逆矩阵,常见大小为 1000 x 1000,但有时超过 100000 x 100000(目前由于时间和内存而失败)。我知道正常的情绪是"不要采取相反的做法,找到其他方法",但目前这是不可能的。这样做的原因是使用了已经制作的软件,该软件希望获得逆矩阵。(注意:我正在研究改变这一点的方法,但这需要很长时间)

目前,我们正在使用来自数值副本的 LU 分解方法,我目前正在测试特征库。特征库似乎更稳定,速度更快,但我仍处于准确性测试阶段。我已经快速浏览了其他库,如ATLAS和LAPACK,但还没有对这些库进行任何实质性的测试。

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

第一个问题是,任何人都可以解释如何通过并行化优化矩阵反演。我在这里找到了一篇关于矩阵反演并行算法的文章,但我不明白。这篇文章似乎在谈论另一种方法?我也不确定scaLAPACK或PETSc是否有用?

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

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

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

第一个问题是谁能解释如何通过并行化来优化矩阵反演。

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

第二个问题...

如果您有 GPU,请使用它们,并且您有能力将代码转换为 GPU 支持的编程模型。 如果您从未为 GPU 编写代码,并且可以访问商品型 CPU 集群,那么使用集群比与新技术搏斗更快地

上手。

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

最后,我强烈支持你显然打算使用现有的现成代码,而不是试图开发自己的代码。

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

关于第一个问题(如何并行计算逆):

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

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

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

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

我知道

这是旧帖子 - 但真的 - OpenCL(您根据显卡下载相关的)+ OpenMP +矢量化(不按该顺序)是要走的路。

无论如何 - 对我来说,我对矩阵的经验实际上与将双精度数组复制到系统和系统的开销有关,并且在任何开始计算之前用 0 填充或初始化矩阵 - 特别是当我使用 Excel 创建 .xll 时。

如果我要重新确定顶部的优先级——

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

对于 2 和 3 - 请记住,开销是产生的,所以除非您正在处理 F*K*G 巨大的矩阵,否则没有意义 - 但我看到 100k^2? 哇...

基因

相关内容

  • 没有找到相关文章