it was, but I was talking to one of the engineers back in the Sun days and expressing my frustration with JNI being hard to use. That's when he said it had been developed that way to encourage people NOT to use it… — Simon Ritter, Deputy CTO of Azul 難用是刻意設計的結果,不是意外
float sum = 0f; for (int i = 0; i < a.length; i++) { sum += a[i] * b[i]; } static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED; FloatVector vsum = FloatVector.zero(SPECIES); int upperBound = SPECIES.loopBound(a.length); for (int i = 0; i < upperBound; i += SPECIES.length()) { var va = FloatVector.fromArray(SPECIES, a, i); var vb = FloatVector.fromArray(SPECIES, b, i); vsum = va.fma(vb, vsum); // vsum += va * vb } float sum = vsum.reduceLanes(VectorOperators.ADD); // tail elements handled separately 程式碼確實變長了。換來的是,你寫什麼指令就得到什麼指令
向量版:整體架構 for (int px = 0; px < width; px += SPECIES.length()) { FloatVector cx = FloatVector.fromArray(SPECIES, cxs, px); FloatVector cy = FloatVector.broadcast(SPECIES, cyScalar); FloatVector x = FloatVector.zero(SPECIES); FloatVector y = FloatVector.zero(SPECIES); FloatVector iter = FloatVector.zero(SPECIES); for (int i = 0; i < maxIter; i++) { // the same arithmetic, on whole vectors // + three lines that do the real work } iter.intoArray(iterCounts, px); } • 外層迴圈每次前進 SPECIES.length() 個像素 • while 變成了 for ── 固定 次數,最多跑到 maxIter • 「這個像素何時停止?」從迴 圈條件裡移了出去
實測數字 時間 加速比 純量 2685 ms 1.0× Vector API / ARM NEON – 4 lanes 775 ms 3.46× Vector API / AVX-512 – 16 lanes 288 ms 9.32× 為什麼加速比不等於 lane 數? 提早發散的 lane 仍要等到同一組裡最後一個 lane 結束。每一組都得為最慢的那個像素付出代價 這不就是平行運算嗎? 不是 ── 這是單一執行緒、單一核心。SIMD 是「寬度」,不是執行緒數量。而且兩者可以疊加
Function & Memory API — https://openjdk.org/jeps/454 • JEP 472: Prepare to Restrict the Use of JNI — https://openjdk.org/jeps/472 • JEP 529: Vector API (Eleventh Incubator) — https://openjdk.org/jeps/529 • JEP 401: Value Objects (Preview) — https://openjdk.org/jeps/401 • JEP draft: Integrity by Default — https://openjdk.org/jeps/8305968 • Project Babylon — https://openjdk.org/projects/babylon/ • jextract — https://jdk.java.net/jextract/ • Pi4J — https://www.pi4j.com/