8

我对 Java 数值算法的性能很好奇,例如矩阵矩阵双精度乘法,使用最新的 JIT 机器,例如与手动调整的 SSE C++/汇编器或 Fortran 对应物相比。

我在网上看过,但大部分结果来自近 10 年前,我知道 Java 从那时起取得了很大进步。

如果您有使用 Java 进行数字密集型应用程序的经验,您可以分享您的经验。此外,Java 在循环相对较短且内存访问不是很均匀但仍在 L1 缓存范围内的内核中表现如何?如果这样的内核连续执行多次,JVM可以在运行时对其进行优化吗?

谢谢

4

9 回答 9

2

我用 Java 编写了一些相当大且对性能敏感的数字代码(通常处理大型双精度数组)。

我发现 Java 对于快速数值计算来说“足够好”。尤其是当您考虑到您通常不受 CPU 限制时 - 内存延迟和缓存感知可能是大型数据集的最大问题。

但是,您仍然可以使用手动优化的 C/C++ 代码击败 Java,这些代码利用特定的矢量化指令等或高度自定义的内存布局。因此,对于最快的代码,您可以考虑用 C/C++ 编写核心算法并使用 JNI 从 Java 调用它。

就个人而言,我发现创建本机代码依赖项通常比其价值更麻烦,因此我倾向于坚持纯 Java 方法。

于 2011-03-14T17:36:37.660 回答
1

是一个指向 java vs c++ 的编程语言枪战页面的链接,它将让您比较 java 在几种计算密集型算法上的速度。它还将向您展示最高性能的 java 代码是什么样的。在大多数情况下,对于这几个特定的​​基准测试,java 需要更多时间(但不超过 2 或 3 次)来运行。

于 2009-11-09T01:15:26.880 回答
1

这来自 .NET 方面,但我 90% 确信 Java 也是如此。虽然 JIT 会在可能的情况下使用 SSE 指令,但它目前在处理(例如)矩阵乘法时不会自动矢量化您的代码。使用编译器内在函数/内联汇编的手动矢量化 C++ 在这里肯定会更快。

于 2009-11-09T01:15:27.220 回答
1

C++ 肯定会更快。您甚至可以为您的目的使用一些手动优化的库,其中包含每个主要 CPU 的汇编代码。你不能比那更好。

之后,如果需要,您可以使用 JNI 从 Java 调用它。

Java 不适用于像这样的高性能算术计算。如果您依赖这些,我建议您选择一种适当的低级语言来实现它。或者,您也可以使用低级语言编写特定于性能的部分,然后使用 JNI 或其他 IPC 方法将其连接到 Java 前端。

于 2009-11-09T15:28:21.027 回答
1

Java 中最薄弱的环节之一是(本机)矩阵运算。这是由于 Java 矩阵的性质:

  • 您不能将矩阵声明为矩形,即。每行可以有不同数量的列。

  • 矩阵在技术上不是“双精度(或整数,...)的矩阵”,而是...的数组数组。最大的区别在于,由于数组是 Java 对象,因此您可以将相同的数组对象分配给超过 1 行。

这两个属性使编译器无法进行许多标准矩阵优化。

通过使用在单个长数组上模拟矩阵的 Java 库,您可能会获得更好的性能。但是,您有所有访问的方法调用的开销。

于 2009-11-09T02:57:41.527 回答
0

附议您最好的选择是自己测试它,因为性能会有所不同,具体取决于您正在做什么。我很难相信 Shane C. Mason 的回答,即 Java 性能将与 C++ 或 Fortran 性能相同,因为对于某些科学计算算法,即使 C++ 和 Fortran 也不能真正具有可比性。

我有一个使用 C++ 编写的计算流体动力学代码,并且基本上将相同的代码翻译成 Fortran。我还不确定为什么,但 Fortran 版本的速度大约是 C++ 版本的两倍。我猜想使用边界检查和垃圾收集等功能,Java 会比两者都慢,但直到我测试后我才知道。

于 2009-11-09T01:14:49.613 回答
0

这可能取决于您在 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++,因为这些语言更适合这种类型的工作。

于 2009-11-09T01:35:27.090 回答
0

您是否对这些计算感兴趣 - 快速傅里叶变换、雅可比连续松弛、蒙特卡洛积分、稀疏矩阵乘法、密集 LU 矩阵分解?

它们构成了SciMark 2.0 复合基准,您可以将其作为小程序在您的机器上启动。

还有程序的ANSI C 版本,以及关于优化和重新编译 SciMark for C++的英特尔文档 (pdf) 。


同样,您可以使用The Java Grande Forum Benchmark Suite比较 C 程序

于 2009-11-09T17:52:37.577 回答
-4

Java 使用即时 (JIT) 编译器将字节码转换为本地机器语言 - 因此它第一次运行代码块时会比较慢,但一旦“预热”该段,性能将是相当的。简而言之 - 数值性能相当不错。

于 2009-11-09T01:05:12.003 回答