【问题标题】:Slow matrix multiplication performance using MTJ/Netlib (native)使用 MTJ/Netlib(本机)的缓慢矩阵乘法性能
【发布时间】:2013-11-28 05:47:16
【问题描述】:

我需要将大小为 5000x5000 的大矩阵乘以 20000x20000。我在查找具有稀疏矩阵但可以进行快速乘法的库时遇到问题。

首先,我已经阅读了上一个关于 Java 矩阵库性能的问题 (Performance of Java matrix math libraries?)。基于那里的最佳答案,我决定使用 JBLAS,因为它是最快的之一。就我而言,乘以 5000x5000 矩阵大约需要 50 秒左右,这比 Matlab 慢很多,但仍然可以忍受。

问题是矩阵可能非常大(最多 20k x 20k 或更多),但它们通常很稀疏。矩阵中只有 30% 的元素是非零的。 JBLAS 不提供任何稀疏矩阵实现,因此存储大型密集矩阵所需的内存占用可能会非常高。我尝试切换到 MTJ/Netlib,因为它应该是基准测试中具有稀疏矩阵的更好的库之一。这里的注释 (https://github.com/fommil/netlib-java/) 说要获得最佳性能,我必须在我的机器上编译原生 BLAS。所以我下载了 OpenBLAS,编译并安装了它。我还运行了一些命令来在 Ubuntu 13.10 上设置 OpenBLAS 库:

$ cd ~/build/OpenBLAS
$ make
$ sudo make install PREFIX=/usr/local/openblas
$ sudo cat "/usr/local/openblas/lib" > /etc/ld.so.conf.d/openblas.conf
$ sudo ldconfig
$ sudo update-alternatives --install /usr/lib/libblas.so.3 libblas.so.3 /usr/local/openblas/lib/libopenblas.so 90
$ sudo update-alternatives --config libblas.so.3

我在最后一个更新替代步骤中选择了我编译的 OpenBLAS 库。我假设在此之后,Netlib 拿起我编译的 OpenBLAS 库并使用它。我还从http://r.research.att.com/benchmarks/R-benchmark-25.R 运行了一些基准测试,并观察到之前(使用来自 ubuntu 的默认 blas)和之后(使用我编译的 OpenBLAS)的一些加速。

但是,MTJ 中的矩阵-矩阵乘法性能仍然很慢。例如,我有两个矩阵 A = 5824x5824,W = 5824x4782。我在Java中像这样将它们相乘

Matrix AW = new FlexCompRowMatrix(A.numRows(), W.numColumns());
A.mult(W, AW);

代码已经运行了超过 45 分钟,足以输入整篇文章,但仍未完成。使用 JBLAS,相同的矩阵乘法只需不到 1 分钟。有什么我错过的吗?

谢谢!

【问题讨论】:

  • 我还尝试了预编译的多线程 OpenBLAS 库(personal.psu.edu/mar36/blogs/the_ubuntu_r_blog/2013/08/…),以为我在编译过程中搞砸了。但是没有任何变化,使用 MTJ/Netlib 的矩阵-矩阵乘法仍然很慢。也许问题是,即使我根本不需要配置任何东西,JBLAS 怎么能(相对)快速地做到这一点?
  • 请问20000x20000矩阵相乘的目的是什么?据我所知,我没有看到任何应用程序(目前)。
  • 嗯,20k x 20k 是相当大的。尽管如此,我认为 5k x 5k 矩阵还是很合理的,而且它一直在运行......
  • @MartijnCourteaux,有数以千计的问题需要将大于 20k 个元素的矩阵相乘非常非常。从 PDE 解决方案到化学反应建模,再到 DNA 测序,应有尽有。更不用说基本的矩阵分解了。这不仅是一个常见问题,而且在许多应用程序中都非常重要。
  • BLAS 规范通常只定义密集和非常特殊的带状矩阵的格式和操作。您应该使用稀疏矩阵库。 -- 通常可以通过仅使用矩阵向量乘积的(近似、迭代)算法来解决涉及稀疏矩阵的任务。

标签: java performance math matrix mtj


【解决方案1】:

http://jeshua.me/blog/NetlibJavaJNI 请注意,您可能必须更新本机包 测试中的名称以演示使用。

例如,可能需要更改: 类 javaBlasClass = Class.forName("org.netlib.blas.JBLAS"); 到: 类 javaBlasClass = com.github.fommil.netlib.BLAS.class;

【讨论】:

    【解决方案2】:

    JBLAS 进行密集矩阵运算。 MJT 既密集又稀疏。以密集方式使用“稀疏”矩阵很慢。 FlexCompRowMatrix 创建一个稀疏矩阵。

    要直接与 JBLAS 进行比较,您想要做的是:

    Matrix a = new DenseMatrix(5000,5000);
    Matrix b = new DenseMatrix(5000,5000);
    Matrix c = new DenseMatrix(5000,5000);
    
    a.multAdd(b, c);
    

    使用 MJT+OpenBlas 的性能应该和 MatLab 差不多。

    【讨论】:

    • 只有在 MATLAB 在后台使用相同的 blas/lapack 时才能与 MATLAB 相媲美 ;-) 顺便说一句,为什么这没有被标记为答案?
    • @jwd 请将此标记为答案,正确。
    • 图书馆作者@fommil 发言,请标记正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 2017-11-06
    • 2013-03-03
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多