如何编写代码以提示JVM使用向量操作?

use*_*775 18 java performance jvm-hotspot

一些相关的问题和一年之久:JVM的JIT编译器是否生成使用向量化浮点指令的代码?

前言:我试图在纯java中执行此操作(没有JNI到C++,没有GPGPU工作等等).我已经进行了分析,并且大部分处理时间来自此方法中的数学运算(可能是95%的浮点数学运算和5%的整数运算).我已经将所有Math.xxx()调用减少到足够好的近似值,因此大部分数学运算现在都是浮点数乘以一些加法.

我有一些处理音频处理的代码.我一直在进行调整,并且已经获得了巨大的收益.现在我正在研究手动循环展开以查看是否有任何好处(至少手动展开2,我看到大约25%的改进).在尝试手动展开4时(由于我展开嵌套循环的两个循环,这开始变得非常复杂)我想知道是否有任何我可以做的提示到jvm在运行时它可以使用向量操作(例如SSE2,AVX等......).音频的每个样本都可以完全独立于其他样本计算,这就是为什么我已经能够看到25%的改进(减少浮点计算的依赖性).

例如,我有4个浮点数,循环的4个展开中的每一个都有一个浮点数来保存部分计算的值.我如何声明和使用这些浮子很重要吗?如果我把它变成一个浮点数[4],它会向jvm暗示它们彼此无关,而不是浮动,浮动,浮动,浮动甚至是一类4个公共浮标?有什么我可以做的没有意义,这会杀死我的代码被矢量化的机会?

我在网上看到有关"正常"编写代码的文章,因为编译器/ jvm知道常见模式以及如何优化它们并偏离模式可能意味着更少的优化.至少在不过这种情况下,我也没有想到2展开环之多具有改进的性能,因为它没有,所以我想知道如果有什么我可以做的(或至少这样做),以帮助我机会.我知道编译器/ jvm只会变得更好所以我也要警惕做将来会伤害我的事情.

编辑为好奇:4展开的提高性能的另一个〜25%,比展开了2,所以我真的觉得向量运算会在我的情况下帮助如果JVM支持它(或者是已经使用它们).

谢谢!

xmo*_*jmr 2

我如何..音频处理..纯java(没有JNI到C++,没有GPGPU工作等...)..使用矢量运算(例如SSE2,AVX等...)

Java 是一种高级语言(Java 中的一条指令生成许多硬件指令),其设计(例如垃圾收集器内存管理)不适合实时操作大量数据的任务。

通常有针对特定角色(例如图像处理语音识别)进行优化的特殊硬件,它们多次通过几个简化的处理管道利用并行化。

还有专门的编程语言用于此类任务,主要是硬件描述语言汇编语言

即使 C++(被认为是快速语言)也不会自动为您使用一些超级优化的硬件操作。它可能只是在某些地方内联了几种手工编写的汇编语言方法之一。

所以我的答案是“可能没有办法”指示 JVM 对代码使用一些硬件优化(例如SSE),即使有一些,Java 语言运行时仍然会有太多其他因素会减慢速度你的代码。

使用为此任务设计的低级语言,并将其链接到 Java 以实现高级逻辑。

编辑:根据评论添加更多信息

如果您确信高级“编写一次,到处运行”语言运行时肯定还应该为您做大量低级优化,并自动将您的高级代码转换为优化的低级代码,那么...JIT 编译器优化的方式取决于Java虚拟机的实现。其中有很多。

对于 Oracle JVM (HotSpot),您可以通过下载源代码开始寻找答案,文本SSE2出现在以下文件中:

  • openjdk/hotspot/src/cpu/x86/vm/assembler_x86.cpp
  • openjdk/hotspot/src/cpu/x86/vm/assembler_x86.hpp
  • openjdk/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
  • openjdk/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
  • openjdk/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
  • openjdk/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
  • openjdk/hotspot/src/cpu/x86/vm/vm_version_x86.hpp
  • openjdk/hotspot/src/cpu/x86/vm/x86_32.ad
  • openjdk/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
  • openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
  • openjdk/hotspot/src/share/vm/c1/c1_LinearScan.cpp
  • openjdk/hotspot/src/share/vm/runtime/globals.hpp

它们采用 C++ 和汇编语言编写,因此您必须学习一些低级语言才能阅读它们。

即使有+500的赏金,我也不会狩猎那么深。恕我直言,这个问题是错误的,基于错误的假设

  • 我知道Java是一种高级语言,我知道你可以使用JNI调用C/C++,但我说这不是一个选择。Java 是“一次编写,随处运行”,而使用 JNI 完全抵消了这一巨大优势。另外,有一些 C++ 编译器会“自动”使用超级优化操作 - 这称为自动向量化,并且一些编译器(例如英特尔编译器)非常擅长(尽管显然并不完美)。我感谢您的回复以及您花时间链接到几个不同的主题,但这并不能真正回答我的问题。 (2认同)