前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 17 更新(11):支持矢量运算,利好科学计算?

Java 17 更新(11):支持矢量运算,利好科学计算?

作者头像
bennyhuo
发布2021-10-19 14:19:49
2.6K0
发布2021-10-19 14:19:49
举报
文章被收录于专栏:Bennyhuo

关键词:Java Java17

Java 17 将继续孵化对矢量计算的支持。

我们这一篇来简单聊聊 JEP 414: Vector API (Second Incubator),之前 Java 16 就已经开始孵化这个项目了。

刚开始看到这个 Vector API,我都懵了,Vector 不是不推荐用吗?后来看到提案的详细内容才明白过来,人家说的是矢量运算,不是我们熟知的那个线程安全的 vector 容器。

在过去,Java 确实没有提供很好的矢量运算的途径,这使得我们只能基于标量计算来构造矢量计算的算法。例如:

代码语言:javascript
复制
static void scalarComputation(float[] a, float[] b, float[] c) {
    for (int i = 0; i < a.length; i++) {
        c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f;
    }
}

这是提案当中给出的例子,a、b、c 是三个相同长度的数组,c 实际上是运算结果。

使用新的 Vector API实现如下:

代码语言:javascript
复制
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;

static void vectorComputation(float[] a, float[] b, float[] c) {
    int i = 0;
    int upperBound = SPECIES.loopBound(a.length);
    for (; i < upperBound; i += SPECIES.length()) {
        // FloatVector va, vb, vc;
        var va = FloatVector.fromArray(SPECIES, a, i);
        var vb = FloatVector.fromArray(SPECIES, b, i);
        var vc = va.mul(va)
            .add(vb.mul(vb))
            .neg();
        vc.intoArray(c, i);
    }
    for (; i < a.length; i++) {
        c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f;
    }
}

Vector API 的基本思想就是批量计算,例子当中的 SPECIES 其实是根据机器来选择合适的分批大小的一个变量。我们可以注意到,在计算时 i 每次增加 SPECIES.length(),这就是分批的大小了。当然,你也可以根据实际情况自己选择,例如调用下面的方法来根据矢量的 shape 来确定大小:

代码语言:javascript
复制
static FloatSpecies species(VectorShape s) {
    Objects.requireNonNull(s);
    switch (s) {
        case S_64_BIT: return (FloatSpecies) SPECIES_64;
        case S_128_BIT: return (FloatSpecies) SPECIES_128;
        case S_256_BIT: return (FloatSpecies) SPECIES_256;
        case S_512_BIT: return (FloatSpecies) SPECIES_512;
        case S_Max_BIT: return (FloatSpecies) SPECIES_MAX;
        default: throw new IllegalArgumentException("Bad shape: " + s);
    }
}

对于 FloatVector 类型,这套 API 提供了诸如 add、mul 这样的方法来方便实现矢量计算,用起来比较方便。

理论上来讲,这套 API 也是可以带来性能上的提升的,但我使用相同的数据调用上述矢量和标量的方法,在提前完成类加载的条件下,粗略得出以下耗时:

代码语言:javascript
复制
scalar: 746000ns
vector: 2210400ns

可以看到新的 Vector API 居然更慢。不过这个也不能说明什么,毕竟实际的使用场景是复杂的,而且也跟 CPU 架构密切相关,我的机器是 AMD R9 5900HX,也许在 Intel 上有更好的表现呢(噗。。)。

对了,因为 Java 自身语法的限制,现在的 Vector API 大量用到了装箱和拆箱(这可能是性能消耗的大头),因此预期在 Valhalla 合入之后,基于值类型再做优化可能会得到大幅的性能提升。这么看来应当不是我的 AMD CPU 的问题。

不管怎么样,这套东西还在很早期的孵化阶段,API 好用就行,性能的事儿后面会解决的(反正我又不会用到)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Kotlin 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
批量计算
批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档