इसलिए, मूल रूप से, आप चाहते हैं कि आपका कोड तेज़ी से चले। जेएनआई इसका जवाब है। मुझे पता है कि आपने कहा था कि यह आपके लिए काम नहीं करता है, लेकिन मैं आपको दिखाता हूं कि आप गलत हैं।
यहाँ है 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 सरणियों के रूप में उपवास के रूप में प्रत्यक्ष NIO बफ़र्स तक पहुँच सकते हैं । दूसरी ओर, लूप को मैन्युअल रूप से अनियंत्रित करने से इस मामले में प्रदर्शन में एक औसत दर्जे का बढ़ावा नहीं मिलता है।
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation
। आपको एक कार्यक्रम की आवश्यकता होगी जो इसे "गर्म" बनाने के लिए वेक्टर करने योग्य विधि को पर्याप्त बार चलाता है।