深入拆解 Java 虚拟机
郑雨迪
Oracle 高级研究员,计算机博士
87446 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 40 讲
模块四:黑科技 (3讲)
深入拆解 Java 虚拟机
15
15
1.0x
00:00/00:00
登录|注册

26 | 向量化

自动向量化的自适配性取决于循环回边的执行次数和方法的执行次数
HotSpot虚拟机使用HotSpot intrinsic和自动向量化两种方式
向量化优化借助CPU的SIMD指令
即时编译器负责将intrinsic方法的调用转换为符合当前体系架构/CPU的SIMD指令
提供通用的跨平台API
Paname项目引入开发人员可控的向量化抽象
C2支持的整数向量化操作有限
触发条件较为苛刻
即时编译器自动向量化针对能够展开的计数循环
仅覆盖特定方法的调用
性能优越但使用麻烦
HotSpot intrinsic方法替换为使用SIMD指令的高效实现
SIMD指令实现向量加法、减法、按位与、或、异或、批量移位和批量乘法
SSE指令集和AVX指令集引入了SIMD指令
使用XMM/YMM/ZMM寄存器进行向量化读取和写入操作
X86_64平台不支持内存间的直接移动
总结与实践
开发人员可控的向量化抽象
自动向量化
使用SIMD指令的HotSpot Intrinsic
SIMD指令
Java虚拟机中的向量化

该思维导图由 AI 生成,仅供参考

在上一篇的实践环节中,我给你留了一个题目:如何进一步优化下面这段代码。
void foo(byte[] dst, byte[] src) {
for (int i = 0; i < dst.length - 4; i += 4) {
dst[i] = src[i];
dst[i+1] = src[i+1];
dst[i+2] = src[i+2];
dst[i+3] = src[i+3];
}
... // post-loop
}
由于 X86_64 平台不支持内存间的直接移动,上面代码中的dst[i] = src[i]通常会被编译为两条内存访问指令:第一条指令把src[i]的值读取至寄存器中,而第二条指令则把寄存器中的值写入至dst[i]中。
因此,上面这段代码中的一个循环迭代将会执行四条内存读取指令,以及四条内存写入指令。
由于数组元素在内存中是连续的,当从src[i]的内存地址处读取 32 位的内容时,我们将一并读取src[i]src[i+3]的值。同样,当向dst[i]的内存地址处写入 32 位的内容时,我们将一并写入dst[i]dst[i+3]的值。
通过综合这两个批量操作,我们可以使用一条内存读取指令以及一条内存写入指令,完成上面代码中循环体内的全部工作。如果我们用x[i:i+3]来指代x[i]x[i+3]合并后的值,那么上述优化可以被表述成如下所示的代码:
void foo(byte[] dst, byte[] src) {
for (int i = 0; i < dst.length - 4; i += 4) {
dst[i:i+3] = src[i:i+3];
}
... // post-loop
}

SIMD 指令

在前面的示例中,我们使用的是 byte 数组,四个数组元素并起来也才 4 个字节。如果换成 int 数组,或者 long 数组,那么四个数组元素并起来将会是 16 字节或 32 字节。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Java虚拟机中的向量化技术是针对性能优化的重要技术。通过使用SIMD指令集,可以实现单指令流多数据流的并行计算,提高代码执行效率。文章介绍了在Java虚拟机中如何利用SIMD指令集进行向量化优化,以及HotSpot虚拟机中的Intrinsic方法的应用。通过使用Intrinsic方法,可以实现对数组操作的高效处理,如复制、比较等。此外,文章还介绍了在不适用Intrinsic方法的情况下,如何借助即时编译器中的自动向量化来实现代码的优化。总的来说,本文深入浅出地介绍了Java虚拟机中的向量化技术,为读者提供了对该技术的全面了解和应用指导。 文章还介绍了即时编译器中的自动向量化优化,借助CPU的SIMD指令实现指令级别的并行计算。HotSpot虚拟机运用向量化优化的方式有两种:使用HotSpot intrinsic和依赖即时编译器进行自动向量化。自动向量化的触发条件较为苛刻,因此无法覆盖大多数用例。为了解决向量化intrinsic以及自动向量化覆盖面过窄的问题,Paname项目尝试引入开发人员可控的向量化抽象,提供一套通用的跨平台API,让Java程序能够定义向量,并使用由它提供的一系列向量化intrinsic方法。最后,文章通过实验展示了即时编译器的自动向量化的自适配性。 总的来说,本文深入探讨了Java虚拟机中的向量化技术及其优化方法,为读者提供了全面的技术指导和实践示例。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Java 虚拟机》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • 小结一下 1:向量化优化-本质是一次性多干一些活,免得来回折腾费时费力,通过减少来回折腾的工作量来提高性能。他是怎么实现的呢?他是借助CPU的SIMD指令,通过单条指令控制多组数据的运算,实现了CPU指令级别的并行。 2:这么好为什么不大批量的使用哪?他有几种方式呢? 使用向量化优化是有一些前提条件的,目前HotSpot 虚拟机运用向量化优化的方式有两种。第一种使用HotSpot intrinsic,在调用特定的方法的时候替换为使用了SIMD指令的高效实现。第二种是依赖即时编译器进行的自动向量化,自动向量化也有苛刻的使用前提条件。

    作者回复: 赞

    2018-09-20
    2
    33
  • Geek_488a8e
    之前用过TI的DSP芯片,里边有很多支持向量处理的计算指令,比如复数乘法,共轭相乘等,但是这些计算指令器不多,而且不能在一个指令周期完成计算,所以大量使用后会影响指令流水,反而不如能在一个指令周期完成计算的单数据加法器

    作者回复: 我们做自动向量化也会考虑值不值得的问题。 比如说X86不能在通用寄存器上计算,有时候需要额外的mov指令移到XMM中(如果不是直接从内存中加载的话)。 另外,某些reduce操作,比如求向量内所有元素的和,X86无法用单条指令实现,只有两两相加的指令,因此需要好几条向量指令协作完成。这种情况下,我们便会放弃自动向量化。

    2018-09-20
    4
  • 饭粒
    dst[i:i+3] = src[i:i+3] 这是伪代码还是新版的 JDK 支持的写法?

    作者回复: 伪代码

    2019-12-25
    1
  • 罗布圆滚滚
    好棒哦!学到很多
    2018-09-19
    5
  • SochiLee
    我看网上说SIMD是单指令多数据,并不是指令并行。
    2021-12-16
    1
  • 李孟聊AI
    1.向量优化借助CPU的SIMD指令,即通过单条指令控制多组数据的运算。它被称为CPU指令级别的并行 2.HotSpot 虚拟机运用向量化优化的方式有两种:HotSpot intrinsic,循环展开优化
    2020-07-07
    1
  • 宋世通
    又一次打开了新世界的大门
    2021-08-26
  • 杨焱
    请问,Java如何面向SIMD变成,多用数组吗?有什么开发技巧?lucene专门用了,但是看不懂
    2021-04-23
  • 任鑫
    写编译器、虚拟机的确实都是大佬
    2020-06-04
  • 有米
    也就是说java因为本身的语言特性限制,无法支持使用到某些CPU指令,从而不能使用它们来进行性能优化?
    2020-04-16
    1
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部