🔍 什么是 Vector API?
Vector API 是一组用于在 Java 中执行向量化计算的标准类库,它允许你在不使用 JNI 或 native 代码的前提下,直接调用底层 CPU 支持的 SIMD 指令,实现对多个数据项的并行处理。
步骤一:最简单的向量加法示例
import jdk.incubator.vector.DoubleVector;
import jdk.incubator.vector.VectorSpecies;
public class VectorAddDemo {
public static void main(String[] args) {
// 定义向量种类(Double 类型)
VectorSpecies<Double> species = DoubleVector.SPECIES_PREFERRED;
// 创建两个输入向量
DoubleVector a = DoubleVector.fromArray(species, new double[]{1.0, 2.0, 3.0, 4.0}, 0);
DoubleVector b = DoubleVector.fromArray(species, new double[]{5.0, 6.0, 7.0, 8.0}, 0);
// 执行向量加法
DoubleVector result = a.add(b);
// 输出结果
double[] resArray = new double[species.length()];
result.intoArray(resArray, 0);
System.out.println("结果:" + java.util.Arrays.toString(resArray));
}
}
输出:
结果:[6.0, 8.0, 10.0, 12.0]
📌 SPECIES_PREFERRED
表示 JVM 自动选择最适合当前 CPU 的向量宽度(如 AVX-512)。
🧪 步骤二:向量化的数组加法函数
public static void vectorAdd(double[] a, double[] b, double[] out) {
int i = 0;
int length = a.length;
VectorSpecies<Double> species = DoubleVector.SPECIES_PREFERRED;
for (; i <= length - species.length(); i += species.length()) {
var va = DoubleVector.fromArray(species, a, i);
var vb = DoubleVector.fromArray(species, b, i);
var vResult = va.add(vb);
vResult.intoArray(out, i);
}
// 处理剩余未对齐的部分
for (; i < length; i++) {
out[i] = a[i] + b[i];
}
}
📌 向量化版本通常比传统循环快 2~8 倍,具体取决于 CPU 架构和数据规模。
🧩 步骤三:图像灰度化处理实战
假设我们有一个 RGB 图像数据存储为字节数组,格式为 [R1, G1, B1, R2, G2, B2, ...]
,我们可以使用向量化方式将其转换为灰度图。
public static void rgbToGrayscale(byte[] rgb, byte[] gray) {
int i = 0;
int length = rgb.length;
VectorSpecies<Byte> species = ByteVector.SPECIES_256;
for (; i <= length - species.length(); i += species.length()) {
var vRgb = ByteVector.fromArray(species, rgb, i);
var vGray = vRgb.mul(0.299).add(vRgb.mul(0.587)).add(vRgb.mul(0.114)).convertShape(...); // 伪代码简化
vGray.intoArray(gray, i);
}
// 处理剩余部分
for (; i < length; i += 3) {
int r = rgb[i] & 0xFF;
int g = (i+1 < length ? rgb[i+1] : 0) & 0xFF;
int b = (i+2 < length ? rgb[i+2] : 0) & 0xFF;
gray[i/3] = (byte)(0.299*r + 0.587*g + 0.114*b);
}
}
📌 利用向量 API,可以显著提升图像处理、信号处理、机器学习等领域的性能表现。
🧨 步骤四:对比传统循环与向量化版本性能
我们可以运行如下测试代码:
double[] a = new double[1000000];
double[] b = new double[1000000];
double[] result = new double[1000000];
// 初始化数组
Arrays.fill(a, 2.0);
Arrays.fill(b, 3.0);
long start = System.nanoTime();
vectorAdd(a, b, result); // 向量化版本
long end = System.nanoTime();
System.out.printf("向量化耗时: %.2f ms%n", (end - start) / 1e6);
start = System.nanoTime();
for (int i = 0; i < a.length; i++) {
result[i] = a[i] + b[i]; // 传统版本
}
end = System.nanoTime();
System.out.printf("传统循环耗时: %.2f ms%n", (end - start) / 1e6);