Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java矩阵数学库的性能?_Java_Math_Matrix_Performance - Fatal编程技术网

Java矩阵数学库的性能?

Java矩阵数学库的性能?,java,math,matrix,performance,Java,Math,Matrix,Performance,我们正在计算一些运行时受矩阵运算约束的东西。(如果有兴趣,请参阅下面的一些详细信息。)这一经历引发了以下问题: 人们是否有关于矩阵数学(例如乘法、求逆等)Java库性能的经验?例如: 我搜索了一下,什么也没找到 我们的速度比较详情: 我们使用的是英特尔FORTRAN(ifort(ifort)10.120070913)。我们已经使用ApacheCommonsMath1.2Matrix ops在Java(1.6)中重新实现了它,并且它与所有精度数字一致。(我们有理由希望它是Java的。)

我们正在计算一些运行时受矩阵运算约束的东西。(如果有兴趣,请参阅下面的一些详细信息。)这一经历引发了以下问题:

人们是否有关于矩阵数学(例如乘法、求逆等)Java库性能的经验?例如:

我搜索了一下,什么也没找到


我们的速度比较详情:

我们使用的是英特尔FORTRAN(ifort(ifort)10.120070913)。我们已经使用ApacheCommonsMath1.2Matrix ops在Java(1.6)中重新实现了它,并且它与所有精度数字一致。(我们有理由希望它是Java的。)(Java Double,Fortran real*8)。Fortran:6分钟,Java 33分钟,同一台机器。jvisualm评测显示了在RealMatrixImpl.{getEntry,isValidCoordination}中花费的大量时间(这似乎在未发布的ApacheCommonsMath2.0中消失了,但2.0并没有更快)。Fortran正在使用Atlas BLAS例程(dpotrf等)

显然,这可能取决于我们在每种语言中的代码,但我们相信大部分时间是在等价的矩阵运算中


在其他几个不涉及库的计算中,Java并没有慢很多,有时甚至快很多。

您有没有看一下?它声称自己的表现甚至超过了其他公司。MKL可以通过JNI包装器来实现。

我不能对特定的库进行评论,但原则上,Java中的此类操作没有什么理由变得更慢。Hotspot通常完成编译器需要完成的任务:它将Java变量上的基本数学运算编译成相应的机器指令(它使用SSE指令,但每个操作只使用一条指令);对数组元素的访问被编译为使用您期望的“原始”MOV指令;它可以决定如何将变量分配给寄存器;它重新排序指令以利用处理器体系结构。。。一个可能的例外是,正如我所提到的,Hotspot对每个SSE指令只执行一个操作;原则上,你可以有一个非常优化的矩阵库,它可以对每条指令执行多个操作,尽管我不知道,比如说,你的特定FORTRAN库是否这样做,或者是否存在这样的库。如果是这样的话,Java(或者至少是Hotspot)目前没有办法与之竞争(尽管您当然可以使用这些优化来编写自己的本机库,以便从Java调用)

那么这一切意味着什么呢?嗯:

  • 原则上,寻找性能更好的库是值得的,但不幸的是,我不能推荐一个
  • <> LI>如果性能对你非常重要,我会考虑只编码你自己的矩阵运算,因为这样你就可以执行某个库通常不能执行的优化,或者你所使用的特定库不(如果你有多处理器机器,查明该库实际上是多线程的)

矩阵运算的一个障碍通常是当需要逐行和逐列遍历时(例如在矩阵乘法中)出现的数据局部性问题,因为必须以优化一个或另一个的顺序存储数据。但是,如果手工编写代码,有时可以组合操作以优化数据局部性(例如,如果将矩阵乘以其变换,则如果编写专用函数而不是组合两个库函数,则可以将列遍历转换为行遍历)。与生活中的通常情况一样,库将为您提供非最佳性能,以换取更快的开发;您需要决定性能对您有多重要。

严重依赖奔腾和更高版本处理器矢量计算能力的Linalg代码(从MMX扩展开始,如LAPACK和现在的Atlas BLAS)不是“梦幻般的优化”,而是行业标准。要在Java中复制这种性能,您需要本机库。我遇到了与您描述的相同的性能问题(主要是为了能够计算Choleski分解),但没有发现任何真正有效的方法:Jama是纯Java,因为它应该只是一个模板和参考工具包,供实现者遵循。。。这从未发生过。你知道阿帕奇数学常识。。。至于COLT,我还需要对它进行测试,但它似乎在很大程度上依赖于Ninja的改进,其中大部分是通过构建一个特别的Java编译器实现的,所以我怀疑它是否会有所帮助。
在这一点上,我认为我们“只是”需要共同努力来构建本机Jama实现…

基于Varkhan的文章,特定于奔腾的本机代码会做得更好:

  • jBLAS:一个alpha阶段项目,带有Atlas的JNI包装器:

    • 作者的博客帖子:
  • MTJ:另一个此类项目:


我们使用柯尔特进行了一些相当大的严肃的财务计算,并对此非常满意。在我们高度剖析的代码中,我们几乎从未用自己的实现替换过COLT实现


在他们自己的测试中(显然不是独立的),我认为他们声称在英特尔手工优化汇编程序的2倍以内。使用它的诀窍是确保您理解他们的设计理念,并避免无关的对象分配。

有许多不同的免费java线性代数库。 不幸的是,基准测试只提供有关矩阵乘法的信息(通过转置测试,不允许不同的库利用它们各自的设计特性)

您应该了解这些线性代数库在被要求计算各种矩阵分解时的性能。

我发现,如果要创建大量高维矩阵,如果将Jama更改为使用一维数组而不是二维数组,则可以使其速度提高约20%。我是贝卡 results execution time --------------------------------------------------------- Octave 36.34 sec JDK 1.7u2 64bit jlapack dgesvd 37.78 sec apache commons math SVD 42.24 sec JDK 1.6u30 64bit jlapack dgesvd 48.68 sec apache commons math SVD 50.59 sec Native routines Lapack* invoked from C: 37.64 sec Intel MKL 6.89 sec(!)
int K = 100;
int N = 100000;
DenseMatrix A = rand(N, K);
DenseMatrix B = rand(K, N);
Timer timer = new Timer();
DenseMatrix C = B.mmul(A);
timer.printTimeCheckMilliseconds();
Jama: 4090 ms
Jblas: 1594 ms
Ojalgo: 2381 ms (using two threads)
Jeigen: 2514 ms