Jadi, pada dasarnya, Anda ingin kode Anda berjalan lebih cepat. JNI adalah jawabannya. Saya tahu Anda mengatakan itu tidak berhasil untuk Anda, tetapi izinkan saya menunjukkan kepada Anda bahwa Anda salah.
Berikut ini 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");
}
}
dan 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;
}
Kita dapat mengkompilasi dan menjalankannya dengan JavaCPP menggunakan perintah ini:
$ java -jar javacpp.jar Dot.java -exec
Dengan CPU Intel (R) Core (TM) i7-7700HQ @ 2.80GHz, Fedora 30, GCC 9.1.1, dan OpenJDK 8 atau 11, saya mendapatkan output semacam ini:
dot(): 39 ns
dotc(): 16 ns
Atau kira-kira 2,4 kali lebih cepat. Kita perlu menggunakan buffer NIO langsung daripada array, tetapi HotSpot dapat mengakses buffer NIO langsung secepat array . Di sisi lain, membuka loop secara manual tidak memberikan peningkatan kinerja yang terukur, dalam kasus ini.
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation
. Anda memerlukan program yang menjalankan metode vectorizable cukup sering untuk membuatnya "panas".