Det låter rätt mycket som java-streams och C++-ranges, men då dessa inte är en nyhet i vare sig Java 20 eller C++-23 gissar jag att du inte menade det.
Menar du Java vector API? Fast stämmer inte riktigt heller då jag motsvarande i C++ fortfarande är markerat som experimentellt, kan komma med i C++-26.
Explicit SIMD-stöd har flera orsaker.
Dels måste det vara explicit då det har visat sig vara i praktiken omöjligt att effektivt generera vektoriserade kod för mer än de mest triviala fallen från "vanlig C++, Java, liknande språk".
Dels vill man få ett sådan stöd då x86_64 (SSE, AVX, AVX-512), ARM64 (NEON, SVE, SVE2) och RISC-V håller på att designa motsvarande. D.v.s. CPU-tillverkarna lägger rätt mycket kiselyta på detta så det är önskvärt att utnyttja detta så bra som möjligt.
Ett stort problem med SIMD på x86_64 är att både instruktionerna och dess registerbredd beror på vilken version av stödet man vill använda. Även om ARM64 lyckades ha samma instruktioner oavsett vektor-registerbredd med SVE/SVE2, kvarstår fortfarande anpassningen till registerbredden.
Som jag förstår det har Javas vector API gått från experimentellt till "färdig" i Java 20
Exempel på både streams (som relativt enkelt kan använda flera CPU-kärnor) och vector APU (som kan använda den SIMD bredd som stöd av den aktuella CPUn)
vectorMultiply() är exempel på hur man kan använda SIMD och streamMultiply() är exempel på hur man kan använda flera CPU-kärnor för att multiplicera innehållet i två array:er. (Dåligt exempel för att visa vinsten med teknikerna, men visar hur man använder APIerna).
import java.util.stream.IntStream;
import jdk.incubator.vector.*;
class App {
static final VectorSpecies<Double> SPECIES = DoubleVector.SPECIES_PREFERRED;
static double[] vectorMultiply(double[] a, double[] b) {
if (a.length != b.length) {
throw new IllegalArgumentException("Argument arrays must have the same length");
}
double[] c = new double[a.length];
for (int i = 0; i < a.length; i += SPECIES.length()) {
VectorMask<Double> m = SPECIES.indexInRange(i, a.length);
DoubleVector va = DoubleVector.fromArray(SPECIES, a, i, m);
DoubleVector vb = DoubleVector.fromArray(SPECIES, b, i, m);
DoubleVector vc = va.mul(vb);
vc.intoArray(c, i, m);
}
return c;
}
static void simd(double[] a, double[] b) {
double[] c = vectorMultiply(a, b);
System.out.printf("vector length: %d\n", SPECIES.length());
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
static double[] streamMultiply(double[] a, double[] b) {
return IntStream
.range(0, a.length)
.parallel()
.mapToDouble(i -> a[i] * b[i])
.toArray();
}
static void par(double[] a, double[] b) {
double[] c = streamMultiply(a, b);
System.out.printf("number of cores : %d\n", Runtime.getRuntime().availableProcessors());
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
public static void main(String[] args) {
int N = 32;
double[] a = new double[N];
double[] b = new double[N];
for (int n = 0; n < N; n++) {
a[n] = n + 1;
b[n] = n + 11;
}
simd(a, b);
par(a, b);
}
}