我对Java数值算法的性能很感兴趣,比如矩阵矩阵双精度乘法,使用最新的JIT机器与手动调整的SSE C++/汇编或Fortran相比如何。
我在网上搜索过,但大多数结果都来自将近10年前,我了解到Java从那时起已经有了很大的进步。
如果您有使用Java进行数值密集型应用程序的经验,可以分享一下您的经验。此外,Java在内核中的表现如何,其中循环相对较短且内存访问不太均匀,但仍在L1缓存的限制范围内?如果这样的内核连续执行多次,JVM能在运行时优化它吗?
谢谢
我对Java数值算法的性能很感兴趣,比如矩阵矩阵双精度乘法,使用最新的JIT机器与手动调整的SSE C++/汇编或Fortran相比如何。
我在网上搜索过,但大多数结果都来自将近10年前,我了解到Java从那时起已经有了很大的进步。
如果您有使用Java进行数值密集型应用程序的经验,可以分享一下您的经验。此外,Java在内核中的表现如何,其中循环相对较短且内存访问不太均匀,但仍在L1缓存的限制范围内?如果这样的内核连续执行多次,JVM能在运行时优化它吗?
谢谢
这里是Java与C++编程语言对比页面的链接,它将为您提供Java在多个计算密集型算法上的速度比较。它还将展示给您最高性能的Java代码是什么样子的。就这几个特定的基准测试而言,Java大部分情况下需要更长的时间来运行(但不超过2或3倍)。
您无法声明矩阵为矩形,即每行可以具有不同数量的列。
严格来说,矩阵并不是“double(或int等)的矩阵”,而是一个数组的数组...。最大的区别在于,由于数组是Java对象,因此可以将相同的数组对象分配给多个行。
java.awt.image.Kernel
,其中有一个通过1D数组表示的矩阵示例。 - finnwfor(int i=0; i<m; i++) { x = a[i]; ...}
聪明的编译器可以在开头添加一个if语句来检查i m是否小于或等于a[]的长度,如果为真,则可以完全消除for循环中的所有边界检查(如果还可以确定m不会改变)。这也适用于嵌套的for循环,在矩阵操作中非常常见,因此可以节省大量检查。 - CarstenC++肯定会更快。您甚至可以拥有一些手动优化的库,其中包含每个主要CPU的汇编代码,以满足您的需求。这是最好的选择。
之后,如果需要,您可以使用JNI从Java中调用它。
Java不适合进行高性能算术计算。如果您依赖于这些计算,请选择一个适当的低级语言来实现它。或者,您可以使用低级语言编写性能特定的部分,然后使用JNI或其他IPC方法将其连接到Java前端。
建议您最好自己测试一下,因为性能会因您所做的具体操作而有所不同。我很难相信Shane C. Mason的回答,即Java的性能将与C++或Fortran的性能相同,因为即使对于某些科学计算算法,C++和Fortran也不能真正进行比较。
我编写了一个使用C++编写的计算流体力学代码,以及基本上翻译成Fortran的相同代码。我还不确定原因,但Fortran版本大约比C++版本快两倍。我猜想,像边界检查和垃圾收集等功能,Java的速度会比两者都慢,但在测试之前我无从得知。
这取决于你在C++代码中做什么。
例如,你是否使用GPU?编辑我忘记了jogl,所以Java在这方面可以竞争。
如果你使用STM或共享内存并行化,那么Java无法竞争。关于并行矩阵乘法分析的链接:http://www.cs.utexas.edu/users/plapack/papers/ipps98/ipps98.html
你是否有足够的内存来进行计算,这样就不需要垃圾回收器,并且你是否调整了垃圾回收器以获得最佳性能?那么,Java可能会有竞争力。
你是否使用多核,而且C++是否经过优化以利用这种架构?那么Java将无法竞争。
你是否使用多台计算机连接在一起,那么Java将无法竞争。
如果你使用任何这些组合,那么它将取决于特定的实现。
Java 并不是为了与手工优化的 C++ 程序竞争而设计的,但是调整所需要的时间,是否进行了足够多的计算才会有所作用?Java 将能够在较少的工作量下提供一些合理的速度,但与仅使用 C++ 代码相比,改进并不大。
您可能希望看看是否有比 Haskell 或 Erlang 更好地针对这种类型的工作而设计的改进,例如可以替代 C++。
你对这些计算感兴趣吗 - 快速傅里叶变换、雅可比逐次松弛法、蒙特卡罗积分、稀疏矩阵乘法、密集LU矩阵分解?
它们组成了SciMark 2.0综合基准测试,您可以在您的机器上启动它作为一个小应用程序。
还有ANSI C版本的程序,以及一份Intel文档(pdf)关于优化和重新编译SciMark为C++。