如何编写代码来提示 JVM 使用向量运算?
有点相关的问题,一年前的问题是:是否有任何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比展开2将性能提高约25%,所以我真的认为如果jvm支持它(或者可能已经使用它们),矢量操作在我的情况下会有所帮助。
谢谢!