কোনও জেভিএমের জেআইটি সংকলকগুলি ভেক্টরাইজড ফ্লোটিং পয়েন্ট নির্দেশাবলী ব্যবহার করে এমন কোড তৈরি করে?


95

আসুন ধরা যাক আমার জাভা প্রোগ্রামের বাধাটি হ'ল ভেক্টর ডট পণ্যগুলির একটি গুচ্ছ গণনা করার জন্য কিছু আঁট লুপ। হ্যাঁ আমি প্রোফাইল করেছি, হ্যাঁ এটি বাধা, হ্যা এটি তাৎপর্যপূর্ণ, হ্যাঁ ঠিক কীভাবে অ্যালগোরিদম হয়, হ্যাঁ আমি বাইট কোডটি অনুকূলিত করতে প্রগার্ড চালিয়েছি, ইত্যাদি etc.

কাজটি মূলত ডট পণ্য। যেমনটি হিসাবে, আমার দুটি আছে float[50]এবং আমার জোড়াবিশিষ্ট পণ্যের যোগফলের অঙ্ক করতে হবে। আমি জানি এসএসই বা এমএমএক্সের মতো এই ধরণের অপারেশনগুলি দ্রুত এবং প্রচুর পরিমাণে সঞ্চালনের জন্য প্রসেসরের নির্দেশাবলী উপস্থিত রয়েছে।

হ্যাঁ আমি সম্ভবত জেএনআইতে কিছু নেটিভ কোড লিখে এগুলি অ্যাক্সেস করতে পারি। জেএনআই কলটি বেশ ব্যয়বহুল হয়ে উঠেছে।

আমি জানি আপনি কোন গ্যারান্টি দিতে পারবেন না যে কোনও জেআইটি কী সংকলন করবে বা সংকলন করবে না। এই নির্দেশাবলী ব্যবহার করে কেউ কি কখনও কোনও জেআইটি উত্পন্ন কোডের কথা শুনেছেন? এবং যদি তাই হয় তবে জাভা কোড সম্পর্কে এমন কিছু আছে যা এটি এইভাবে সংকলন করতে সহায়তা করে?

সম্ভবত একটি "না"; জিজ্ঞাসা মূল্য।


4
এটির সর্বাধিক সহজ উপায় সম্ভবত আপনি সর্বাধিক আধুনিক জেআইটি পেতে পারেন এবং এটির সাথে উত্পন্ন সমাবেশটি আউটপুট পেতে পারেন -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation। আপনার এমন একটি প্রোগ্রামের প্রয়োজন হবে যা ভেটোরিজেবল পদ্ধতিটিকে "উত্তপ্ত" করতে পর্যাপ্ত সময় চালায়।
লুই ওয়াসারম্যান

4
বা উত্স তাকান। download.java.net/openjdk/jdk7
বিল

4
আপনার নিকটবর্তী একটি জেডিকে
জোনাথন এস ফিশার

4
আসলে, এই ব্লগ অনুসারে , "সঠিকভাবে" ব্যবহার করা হলে জেএনআই বরং দ্রুত হতে পারে।
ziggystar

4
এটি সম্পর্কিত একটি ব্লগ পোস্ট এখানে পাওয়া যাবে: psy-lob-saw.blogspot.com/2015/04/… সাধারণ বার্তা সহ যে ভেক্টরাইজেশন ঘটতে পারে, এবং ঘটেও । সুনির্দিষ্ট কেসগুলি (অ্যারে.ফিল () / সমান (চর []) / অ্যারেকপি) ভেক্টরাইজিং ছাড়াও সুপারওয়ার্ড লেভেল প্যারালালাইজেশন ব্যবহার করে জেভিএম অটো-ভেক্টরাইজ করে। প্রাসঙ্গিক কোডটি সুপারওয়ার্ড.পি.পি. এবং এর ভিত্তিতে থাকা কাগজটি এখানে রয়েছে: গ্রুপ. csail.mit.edu/cag/slp/SLP-PLDI-2000.pdf
নিতসান ওয়াকার্ট

উত্তর:


45

সুতরাং, মূলত, আপনি চান আপনার কোডটি দ্রুত চালিত হোক। জেএনআই এর উত্তর is আমি জানি আপনি বলেছিলেন এটি আপনার পক্ষে কাজ করে নি, তবে আমাকে ভুল দেখাতে দাও।

এখানে 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;
}

এই কমান্ডটি ব্যবহার করে আমরা জাভাসিপিপি দিয়ে এটি সংকলন ও পরিচালনা করতে পারি :

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

একটি ইন্টেল (আর) কোর (টিএম) আই 7-7700 এইচকিউ সিপিইউ @ 2.80GHz, ফেডোরা 30, জিসিসি 9.1.1, এবং ওপেনজেডিকে 8 বা 11 এর সাথে আমি এই ধরণের আউটপুট পাই:

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

বা প্রায় 2.4 গুণ দ্রুত। অ্যারের পরিবর্তে আমাদের সরাসরি এনআইও বাফার ব্যবহার করা দরকার, তবে হটস্পট সরাসরি এনআইও বাফারগুলিকে অ্যারে হিসাবে দ্রুত অ্যাক্সেস করতে পারে । অন্যদিকে, লুপটি নিজে হাতে আনারোলিং করা এক্ষেত্রে পারফরম্যান্সে একটি পরিমাপযোগ্য উত্সাহ সরবরাহ করে না।


4
আপনি কি ওপেনজেডিকে বা ওরাকল হটস্পট ব্যবহার করেছেন? জনপ্রিয় বিশ্বাসের বিপরীতে, তারা এক নয়।
জোনাথন এস ফিশার

@ এক্স্যাব্রিয়াল এই মুহুর্তে এই যন্ত্রটিতে "জাভা-রূপান্তর" কী প্রত্যাবর্তন করবে: জাভা সংস্করণ "1.6.0_22" ওপেনজেডকে রানটাইম এনভায়রনমেন্ট (আইসডটিয়া 6 1.10.6) (ফেডোরা-63.1.10.6.fc15-x86_64) ওপেনজেডকে 64-বিট সার্ভার ভিএম (20.0-b11, মিশ্র মোড তৈরি করুন)
স্যামুয়েল

4
এই লুপটির সম্ভবত বাহিত লুপ নির্ভরতা রয়েছে। আপনি লুপটি দুটি বা ততোধিক বার নিবন্ধভুক্ত করে আরও গতি অর্জন করতে পারেন।

4
@ অলিভ জিসিসি এসএসই সহ কোডটি ভেক্টরাইজ করেছে, হ্যাঁ, তবে এই জাতীয় ছোট তথ্যের জন্য, জেএনআই কল ওভারহেড দুর্ভাগ্যক্রমে খুব বড়।
স্যামুয়েল অডিট

4
JDK 13 এর সাথে আমার A6-7310 এ, আমি পেয়েছি: বিন্দু (): 69 এনএস / ডটক (): 95 এনএস জাভা জিতল!
স্টেফান রেইচ

40

অন্যের দ্বারা প্রকাশিত কিছু সংশয়কে সমাধান করার জন্য আমি এখানে যে কেউ নিজের বা অন্যটি প্রমাণ করতে চায় নিম্নলিখিত পদ্ধতিটি ব্যবহার করতে চাই:

  • একটি জেএমএইচ প্রকল্প তৈরি করুন
  • ভেক্টরিজেবল গণিতের একটি ছোট স্নিপেট লিখুন।
  • এক্সএক্স: -উপসুপারওয়ার্ড এবং-এক্সএক্স: + ইউজসুপারওয়ার্ড (ডিফল্ট) এর মধ্যে তাদের বেঞ্চমার্কটি ফ্লিপিং চালান
  • যদি পারফরম্যান্সে কোনও পার্থক্য পালন করা না যায়, আপনার কোড সম্ভবত ভেক্টরাইজড হয়নি
  • নিশ্চিত করার জন্য, আপনার মানদণ্ডটি এমনভাবে চালান যাতে এটি বিধানসভা প্রিন্ট করে। লিনাক্সে আপনি পারফাস্ম প্রোফাইলার উপভোগ করতে পারেন ('- প্রোফেস পারফ্যাসম') এবং আপনি যে নির্দেশনাগুলি প্রত্যাশা করেছেন সেগুলি উত্পন্ন হয়েছে কিনা তা দেখুন।

উদাহরণ:

@Benchmark
@CompilerControl(CompilerControl.Mode.DONT_INLINE) //makes looking at assembly easier
public void inc() {
    for (int i=0;i<a.length;i++)
        a[i]++;// a is an int[], I benchmarked with size 32K
}

পতাকা সহ এবং ছাড়াই (সাম্প্রতিক হাসওয়েল ল্যাপটপে, ওরাকল জেডিকে 8u60): -এক্সএক্স: + ইউজসুপারওয়ার্ড: 475.073 ± 44.579 এনএস / অপ (প্রতি ওপরে ন্যানোসেকেন্ডস) -এক্সএক্স: -উসসুপারওয়ার্ড: 3376.364 ± 233.211 এনএস / অপ

হট লুপের জন্য সমাবেশটি এখানে ফর্ম্যাট এবং স্টিক করার জন্য কিছুটা হলেও এখানে একটি স্নিপেট রয়েছে (hsdis.so অ্যাভিএক্স 2 ভেক্টর নির্দেশাবলীর কিছু ফর্ম্যাট করতে ব্যর্থ হওয়ায় আমি -XX: ইউজারএভিএক্স = 1): -এক্সএক্স: + ইউজসুপারওয়ার্ড ('প্রোফাইম পারফ্যাসম: ইন্টেলসিন্ট্যাক্স = সত্য' সহ)

  9.15%   10.90%  │││ │↗    0x00007fc09d1ece60: vmovdqu xmm1,XMMWORD PTR [r10+r9*4+0x18]
 10.63%    9.78%  │││ ││    0x00007fc09d1ece67: vpaddd xmm1,xmm1,xmm0
 12.47%   12.67%  │││ ││    0x00007fc09d1ece6b: movsxd r11,r9d
  8.54%    7.82%  │││ ││    0x00007fc09d1ece6e: vmovdqu xmm2,XMMWORD PTR [r10+r11*4+0x28]
                  │││ ││                                                  ;*iaload
                  │││ ││                                                  ; - psy.lob.saw.VectorMath::inc@17 (line 45)
 10.68%   10.36%  │││ ││    0x00007fc09d1ece75: vmovdqu XMMWORD PTR [r10+r9*4+0x18],xmm1
 10.65%   10.44%  │││ ││    0x00007fc09d1ece7c: vpaddd xmm1,xmm2,xmm0
 10.11%   11.94%  │││ ││    0x00007fc09d1ece80: vmovdqu XMMWORD PTR [r10+r11*4+0x28],xmm1
                  │││ ││                                                  ;*iastore
                  │││ ││                                                  ; - psy.lob.saw.VectorMath::inc@20 (line 45)
 11.19%   12.65%  │││ ││    0x00007fc09d1ece87: add    r9d,0x8            ;*iinc
                  │││ ││                                                  ; - psy.lob.saw.VectorMath::inc@21 (line 44)
  8.38%    9.50%  │││ ││    0x00007fc09d1ece8b: cmp    r9d,ecx
                  │││ │╰    0x00007fc09d1ece8e: jl     0x00007fc09d1ece60  ;*if_icmpge

দুর্গে ঝড় তোলা মজা করুন!


4
একই কাগজ থেকে: "জেআইটিড ডিসেসেমব্লার আউটপুট পরামর্শ দেয় যে সর্বাধিক অনুকূল সিমডি নির্দেশনা এবং তাদের সময়সূচী কল করার ক্ষেত্রে এটি আসলে দক্ষ নয়। প্যাকড সিমডি নির্দেশ কোডের অস্তিত্ব। " এসএসই রেজিস্টারগুলি স্কেলার মোডে ব্যবহৃত হচ্ছে।
আলেকসান্দ্র ডাবিনস্কি

4
@ আলেকসান্ডারডুবিনস্কি কিছু মামলা areেকে রেখেছে, কিছু নেই। আপনার কি আগ্রহী কংক্রিটের কেস আছে?
নিতসান ওয়াকার্ট

4
আসুন প্রশ্নটি উল্টাতে এবং জিজ্ঞাসা করুন যে জেভিএম কোনও পাটিগণিতের ক্রিয়াকলাপকে স্বনির্বাচিত করবে? আপনি একটি উদাহরণ প্রদান করতে পারেন? আমার কাছে এমন একটি লুপ রয়েছে যা সম্প্রতি আমাকে ইন্টার্নিক্স ব্যবহার করে আবার বের করতে এবং পুনরায় লিখতে হয়েছিল। তবে স্বতঃসংশ্লিষ্টকরণের আশা না করে আমি সুস্পষ্ট ভেক্টরাইজেশন / অন্তর্নিবেশগুলির ( অ্যাগ্রনার.আর্গ / আপ্টিমাইজ / ওয়েেক্টরক্লাস.পিডিএফ এর অনুরূপ ) সমর্থন দেখতে চাই । আরও ভাল হবে অপারাপি (যদিও সেই প্রকল্পের নেতৃত্বের কিছু ভুল লক্ষ্য রয়েছে) এর জন্য একটি ভাল জাভা ব্যাকেন্ড লেখার জন্য। আপনি কি JVM এ কাজ করেন?
আলেকসান্দ্র ডাবিনস্কি

4
@ আলেকসান্ডারডুবিনস্কি আমি আশা করি বর্ধিত উত্তরটি সাহায্য করবে, যদি না হয় তবে কোনও ইমেল আসে। এছাড়াও মনে রাখবেন যে "ইন্টার্নিক্স ব্যবহার করে পুনর্লিখন" এর অর্থ আপনি জেভিএম কোডটি নতুন অন্তর্নিহিত যুক্ত করতে পরিবর্তন করেছেন, আপনি কি এটি বোঝাতে চাইছেন? আমি অনুমান করছি আপনি বোঝাচ্ছেন আপনার জাভা কোডটি
জেএনআই-এর

4
ধন্যবাদ. এটি এখন সরকারী উত্তর হওয়া উচিত। আমি মনে করি আপনার কাগজের উল্লেখটি মুছে ফেলা উচিত, যেহেতু এটি পুরানো এবং ভেক্টরাইজেশন প্রদর্শন করে না।
আলেকসান্দ্র ডাবিনস্কি

26

জাভা 7u40 দিয়ে শুরু হটস্পট সংস্করণগুলিতে, সার্ভার সংকলক স্বয়ং-ভেক্টরাইজেশনের জন্য সমর্থন সরবরাহ করে। JDK-6340864 অনুসারে

তবে এটি শুধুমাত্র "সাধারণ লুপগুলি" - এর জন্য অন্তত মুহূর্তের জন্য সত্য বলে মনে হয়। উদাহরণস্বরূপ, একটি অ্যারে জমে জেডিকে -7192383 এখনও ভেক্টরাইজ করা যাবে না


জেডিকে in তেও ভেক্টরাইজেশন রয়েছে কিছু ক্ষেত্রে, যদিও লক্ষ্যযুক্ত সিমডি নির্দেশ সেটটি তত প্রশস্ত নয়।
নিতসান ওয়াকার্ট

4
ইন্টেলের অবদানের কারণে হটস্পট-এ সংকলক ভেক্টরাইজেশন সমর্থন ইদানীং (জুন 2017) অনেক উন্নত হয়েছিল। পারফরম্যান্স অনুসারে এখনও অপ্রকাশিত jdk9 (বি 163 এবং তার পরে) বর্তমানে বাগ-ফিক্সগুলি অ্যাভিএক্স 2 সক্ষম করে জেডকে 8-তে জিতেছে। লুপগুলিকে অটো-ভেক্টরাইজেশনের কাজ করার জন্য কয়েকটি বাধা অবশ্যই পূরণ করতে হবে, যেমন ব্যবহার করুন: ইন্টি কাউন্টার, ধ্রুবক কাউন্টার ইনক্রিমেন্ট, লুপ-ইনভারেন্ট ভেরিয়েবলগুলির সাথে একটি সমাপ্তির শর্ত, পদ্ধতি কল (?) ছাড়াই লুপ বডি, কোনও ম্যানুয়াল লুপ উন্মুক্ত নয়! বিশদগুলি
বেদরান

ভেক্টরাইজড ফিউজড-মাল্টিপল-অ্যাড (এফএমএ) সমর্থনটি বর্তমানে (জুন ২০১ 2017 হিসাবে) ভাল দেখাচ্ছে না: এটি হয় ভেক্টরাইজেশন বা স্কেলার এফএমএ (?)। যাইহোক, ওরাকল স্পষ্টতই হটস্পটে ইন্টেলের অবদানকে গ্রহণ করেছে যা এভিএক্স -512 ব্যবহার করে এফএমএ ভেক্টরাইজেশন সক্ষম করে। স্ব-ভেক্টরাইজেশন অনুরাগীদের এবং এভিএক্স -512 হার্ডওয়্যারের অ্যাক্সেস পাওয়ার জন্য ভাগ্যবানদের আনন্দিত হওয়ার জন্য এটি পরবর্তী কিছু জেডিকে 9 ইএ বিল্ডগুলির (বি 1 75 এর বাইরে) এর মধ্যে উপস্থিত হতে পারে (কিছু ভাগ্য সহ)।
বেদরান

পূর্ববর্তী বিবৃতিটি সমর্থন করার জন্য একটি লিঙ্ক (আরএফআর (এম): 8181616: x86 এফএমএ ভেক্টরাইজেশন): mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2017-
বেদরান

4
একটি ছোট বেঞ্চমার্ক AVX2 নির্দেশাবলী ব্যবহার করে লুপ ভেক্টরাইজেশনের মাধ্যমে পূর্ণসংখ্যার 4 এর গুণক দ্বারা ত্বরণ প্রদর্শন করছে: prestodb.rocks/code/simd
ভেদরান

6

জাভা এবং আমার বন্ধু দ্বারা লিখিত সিমডি নির্দেশাবলী নিয়ে পরীক্ষা সম্পর্কে চমৎকার নিবন্ধটি এখানে: http://prestodb.rocks/code/simd/

এর সাধারণ পরিণতি হ'ল আপনি আশা করতে পারেন যে জেআইটি কিছু এসএসই অপারেশনগুলি 1.8 সালে (এবং আরও কিছু 1.9 তে) ব্যবহার করবে। যদিও আপনার খুব বেশি আশা করা উচিত নয় এবং আপনার সতর্ক হওয়া দরকার।


4
আপনি যে লিখিত লিঙ্কটির নিবন্ধটির কিছু মূল অন্তর্দৃষ্টি সংক্ষিপ্ত করে তা সহায়তা করবে।
আলেকসান্দ্র ডাবিনস্কি

4

আপনি কম্পিউটিং করতে ওপেনসিএল কার্নেল লিখতে এবং এটি জাভা http://www.jocl.org/ থেকে চালাতে পারেন ।

কোডটি সিপিইউ এবং / বা জিপিইউতে চালানো যেতে পারে এবং ওপেনসিএল ভাষাও ভেক্টর প্রকারকে সমর্থন করে যাতে আপনার স্পষ্টতই SSE3 / 4 নির্দেশাবলীর সুবিধা নিতে সক্ষম হওয়া উচিত।


4

কম্পিউটেশনাল মাইক্রো-কার্নেলগুলির সর্বোত্তম বাস্তবায়নের জন্য জাভা এবং জেএনআইয়ের মধ্যে পারফরম্যান্স তুলনা দেখুন । তারা দেখায় যে জাভা হটস্পট ভিএম সার্ভার সংকলক সুপার-ওয়ার্ড লেভেল প্যারালালিজম ব্যবহার করে অটো-ভেক্টরাইজেশন সমর্থন করে যা লুপ সমান্তরালতার অভ্যন্তরের সাধারণ ক্ষেত্রে সীমাবদ্ধ। আপনার নিবন্ধের আকারটি JNI রুটে যাওয়ার পক্ষে যুক্তিযুক্ত করার পক্ষে যথেষ্ট পরিমাণে রয়েছে কিনা তা এই নিবন্ধটি আপনাকে কিছু নির্দেশিকাও দেবে।


3

আমি অনুমান করছি যে আপনি নেটলিব-জাভা ;-) সম্পর্কে জানতে পারার আগে আপনি এই প্রশ্নটি লিখেছিলেন; এটি মেশিন অনুকূলিতকরণ বাস্তবায়নের সাথে আপনার প্রয়োজনীয় নেটিভ এপিআই সরবরাহ করে, এবং মেমরি পিনিংয়ের কারণে দেশীয় সীমানায় কোনও দাম নেই।


4
হ্যাঁ, অনেক আগে আমি আরও শোনার প্রত্যাশায় ছিলাম যে এটি স্বয়ংক্রিয়ভাবে ভেক্টরাইজড নির্দেশিকায় অনুবাদ করা হয়েছে। তবে স্পষ্টতই এটি ম্যানুয়ালি ঘটানো এতটা কঠিন নয়।
শন ওভেন

-4

আমি যদি বিশ্বাস করি যে কোনও ভিএম এই ধরণের অপ্টিমাইজেশনের জন্য সদা যথেষ্ট স্মার্ট থাকে তবে। সুষ্ঠু হওয়ার জন্য সর্বাধিক অপটিমাইজেশনগুলি অনেক সহজ, যেমন দু'জনের পাওয়ারের গুণনের পরিবর্তে স্থানান্তর। মনো প্রকল্পটি তাদের নিজস্ব ভেক্টর এবং অন্যান্য পদ্ধতিগুলি দেশীয় ব্যাকিংয়ের সাথে পারফরম্যান্সে সহায়তা করার জন্য প্রবর্তন করেছিল।


4
বর্তমানে, কোনও জাভা হটস্পট সংকলক এটি করে না, তবে তারা যে কাজগুলি করে তার চেয়ে বেশি শক্ত নয়। তারা একবারে একাধিক অ্যারে মানগুলি অনুলিপি করতে সিমডি নির্দেশাবলী ব্যবহার করে। আপনাকে কেবল আরও কিছু প্যাটার্ন ম্যাচিং এবং কোড জেনারেশন কোড লিখতে হবে যা কিছু লুপ আন্রোলিং করার পরে বেশ সোজা। আমি মনে করি সানের লোকেরা কেবল অলস হয়ে গেছে, তবে দেখে মনে হচ্ছে এটি এখন ওরাকলে ঘটবে (ইয়ে ভ্লাদিমির! এটি আমাদের কোডকে
ক্রিস্টোফার ম্যানিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.