gpt4 book ai didi

java - 是否有任何 JVM 的 JIT 编译器生成使用矢量化浮点指令的代码?

转载 作者:IT老高 更新时间:2023-10-28 11:35:13 24 4
gpt4 key购买 nike

假设我的 Java 程序的瓶颈确实是一些紧密循环来计算一堆 vector 点积。是的,我已经分析过了,是的,它是瓶颈,是的,它很重要,是的,算法就是这样,是的,我已经运行 Proguard 来优化字节码,等等。

这项工作本质上是点积。如,我有两个 float[50] ,我需要计算成对产品的总和。我知道处理器指令集的存在是为了快速批量执行此类操作,例如 SSE 或 MMX。

是的,我可以通过在 JNI 中编写一些 native 代码来访问这些。事实证明,JNI 调用非常昂贵。

我知道你不能保证 JIT 会编译什么,什么不编译。有没有人曾经听说过使用这些指令的 JIT 生成代码?如果是这样,Java 代码有什么东西可以帮助它以这种方式编译吗?

可能是“不”;值得一问。

最佳答案

所以,基本上,您希望您的代码运行得更快。 JNI 就是答案。我知道你说它对你不起作用,但让我告诉你你错了。

这里是 Dot.java:

import java.nio.FloatBuffer;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;

@Platform(include = "Dot.h", compiler = "fastfpu")
public class Dot {
static { Loader.load(); }

static float[] a = new float[50], b = new float[50];
static float dot() {
float sum = 0;
for (int i = 0; i < 50; i++) {
sum += a[i]*b[i];
}
return sum;
}
static native @MemberGetter FloatPointer ac();
static native @MemberGetter FloatPointer bc();
static native @NoException float dotc();

public static void main(String[] args) {
FloatBuffer ab = ac().capacity(50).asBuffer();
FloatBuffer bb = bc().capacity(50).asBuffer();

for (int i = 0; i < 10000000; i++) {
a[i%50] = b[i%50] = dot();
float sum = dotc();
ab.put(i%50, sum);
bb.put(i%50, sum);
}
long t1 = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
a[i%50] = b[i%50] = dot();
}
long t2 = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
float sum = dotc();
ab.put(i%50, sum);
bb.put(i%50, sum);
}
long t3 = System.nanoTime();
System.out.println("dot(): " + (t2 - t1)/10000000 + " ns");
System.out.println("dotc(): " + (t3 - t2)/10000000 + " ns");
}
}

Dot.h:

float ac[50], bc[50];

inline float dotc() {
float sum = 0;
for (int i = 0; i < 50; i++) {
sum += ac[i]*bc[i];
}
return sum;
}

我们可以用 JavaCPP 编译和运行它使用这个命令:

$ java -jar javacpp.jar Dot.java -exec

使用 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz、Fedora 30、GCC 9.1.1 和 OpenJDK 8 或 11,我得到这样的输出:

dot(): 39 ns
dotc(): 16 ns

或大约快 2.4 倍。我们需要使用直接 NIO 缓冲区而不是数组,但是 HotSpot can access direct NIO buffers as fast as arrays .另一方面,在这种情况下,手动展开循环并不能显着提升性能。

关于java - 是否有任何 JVM 的 JIT 编译器生成使用矢量化浮点指令的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10784951/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com