0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在AArch64平台上性能下降的例子

Linux阅码场 来源:openEuler 作者:吴言 2021-09-09 11:11 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

编者按:目前许多公司同时使用 x86 和 AArch64 2 种主流的服务器。这两种环境的算力相当,内存相同的情况下:相同版本的 JVM 和 Java 应用,相同的 JVM 参数,应用性能在不同的平台中表现相差 30%,x86 远好于 AArch64 平台。本文分析了一个应用在 AArch64 平台上性能下降的例子,发现 JVM 的 CodeCache 大小是引起这个性能问题的根源,进而研究什么导致了不同平台上 CodeCache 大小的不同。最后笔者给出了不同平台中该如何设置参数规避该问题。希望本文能给读者一些启示:当使用不同的硬件平台时需要关注底层硬件对于上层应用的影响。

业务在 x86 和 AArch64 上同时部署时(相同的 JDK 和 Java 应用版本),发现 AArch64 平台性能下降严重问题。进一步查看日志,发现在 AArch64 平台中偶有如下情况:

这代表 JVM 中的 CodeCache 满了,导致编译停止,未编译的方法只能解释执行,进而严重影响应用性能。那什么是 CodeCache?

CodeCache 是什么

简单来说,CodeCache 用于存放编译后的方法,主要分为三部分:

Non-nmethods:包括运行时 Stub,Adapter 等;

Profiled nmethod:包括会采集信息的方法,即分层编译中第 2、3 层的方法;

Non-Profiled nmethods:包括不采集信息的方法,即分层编译中第 1、4 层的方法,也包括 JNI 的方法。

注:分层编译指的是 JVM 同时存在 C1 和 C2 两种编译器,C1 做一些简单的编译优化,耗时较短,C2 做更多复杂的编译优化,性能较好,编译耗时较多。分层编译的触发在 JVM 内会根据相应的条件进行触发,关于更多分层编译相关知识可以参考相关资料 [1]。

在 JDK 9 之后 [2],这些会分配到不同的区域(使用不同区域的优点:查找、回收等),JDK 8 中会分配到同一块区域。

JVM 平时会清理一些不可达的方法,例如由于退优化等产生的死方法,另外 UseCodeCacheFlushing 选项(默认开启),还会清理较老以及执行较少的方法。一旦 CodeCache 满了之后,会停止编译,直到 CodeCache 有空间,若关闭了 UseCodeCacheFlushing 选项,则会直接永久停止编译。

不同的 JVM 版本以及不同的参数,默认的 CodeCache 大小不同。JDK 11 中默认参数下 CodeCache 大小为 240M,若想获取(确认)默认情况下的 CodeCache 大小,建议使用 - XX:+PrintFlagsFinal 选项获取 ReservedCodeCache 的大小。

CodeCache 大小主要通过以下选项调节:

InitialCodeCacheSize 初始的 CodeCache 大小(单位字节)
ReservedCodeCacheSize 预留的 CodeCache 大小,即最大CodeCache 大小(单位字节)
CodeCacheExpansionSize CodeCache 每次扩展大小(单位字节)
Option Description

使用–XX:+PrintCodeCache 选项可以打印应用使用的 CodeCache 情况,如下:

其中 max_used 表示应用中使用到的 CodeCache 大小,据此可以设置合适的 ReservedCodeCacheSize 值。

AArch64 vs x86_64

我们都知道 AArch64 和 x86 分别为 RISC 和 CISC 架构,因此代码密度方面存在一定差异,在这篇文章 [3] 中比较了不同指令集下手写汇编的大小,可以看到 AArch64 的代码密度是 RISC 架构中较优的,但相比 x86_64 仍稍差些(其中 RISC 最差,m68k 最好)。

另外笔者选用业界通用的 java 测试套 dacapo[4] 比较 AArch64 和 x86_64 下 CodeCache 占用的大小。

可以看到,在 AArch64 架构下,CodeCache 均比 x86_64 要大,但根据不同场景,大小差距不同,在 5%-20% 之间。因此在我们发现相同应用在 x86 和 AArch64 上时,CodeCache 大小需要进行相应的调节。

除此之外,还需要注意 InlineSmallCode 选项,JVM 只会 inline 代码体积比该值小的方法。JVM 通过 inline 可以触发更多的优化,因此 inline 对于性能提升也很重要。在 JDK 11 中,InlineSmallCode 在 x86 下的默认值为 2000 字节,在 AArch64 下的默认值为 2500 字节。而 JDK 8 中,InlineSmallCode 在 x86 和 AArch64 下默认值均为 2000 字节。因此建议迁移时也相应修改 InlineSmallCode 的值。业务通过对 CodeCache 相关参数的调整,达到助力 JIT 的最佳编译效果。

后记

如果遇到相关技术问题(包括不限于毕昇 JDK),可以进入毕昇 JDK 社区查找相关资源(点击原文进入官网),包括二进制下载、代码仓库、使用教学、安装、学习资料等。毕昇 JDK 社区每双周周二举行技术例会,同时有一个技术交流群讨论 GCC、LLVM、JDK 和 V8 等相关编译技术,感兴趣的同学可以添加如下微信小助手,回复 Compiler 入群。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    13

    文章

    10093

    浏览量

    90889
  • JAVA
    +关注

    关注

    20

    文章

    2997

    浏览量

    115684
  • JVM
    JVM
    +关注

    关注

    0

    文章

    161

    浏览量

    12957

原文标题:相同版本 JVM 和 Java 应用,在 x86 和AArch64 平台性能相差30%,何故?

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    NVIDIA DGX Spark平台上对NVIDIA ConnectX-7 200G网卡配置教程

    NVIDIA DGX Spark 平台上对 NVIDIA ConnectX-7 200G 网卡进行配置时,会遇到“4 个逻辑端口”现象。理解背后的真相是后续所有配置的基础。本文将从此现象入手,逐步解析其原理,并提供从基础配置到深度
    的头像 发表于 11-21 09:19 4426次阅读
    <b class='flag-5'>在</b>NVIDIA DGX Spark<b class='flag-5'>平台上</b>对NVIDIA ConnectX-7 200G网卡配置教程

    如何把蜂鸟E203的核移植N4DDR平台上

    请问一下我想把蜂鸟E203的核移植N4DDR平台上,但是他们的约束文件及硬件电路区别很大,具体我该怎么修改呢?比如蜂鸟的核中只有4个拨码开关而N4DDR上有16个拨码开关。
    发表于 11-10 06:46

    【Milk-V Duo S 开发板免费体验】Milk-V DuoS性能测试

    ,因为是WSL下执行coremark的err,WSL是X86,交叉编译出来的持续是AARCH64的,必须不能运行嘛~ 看看文件: ~/duo-examples/coremark$ file
    发表于 08-09 23:32

    【Milk-V Duo S 开发板免费体验】测试舵机

    executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64
    发表于 08-09 22:46

    【HZ-T536开发板免费体验】3 - Cangjie Magic调用视觉语言大模型(VLM)真香,是不是可以没有YOLO和OCR了?

    ,缺少对嵌入式开发板的测试。本文主要讨论AARCH64的Linux平台,这个也是目前嵌入式开发板中最多的平台之一。 我们使用的是交叉编译,虽然T536开发板的能力很强,本地编译也可以
    发表于 08-01 22:15

    【HZ-RK3568开发板免费体验】3、开启Linux Kernel RT功能

    =../prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin
    发表于 07-22 14:03

    【HZ-T536开发板免费体验】2 - 交叉编译仓颉编程语言程序到开发板运行

    /aarch64-linux-gnu/lib/libstdc++.so 程序运行 将程序拷贝到板子运行,得到如下结果: 运行结果正确。和0.53版本比较,1.0版本的static选项比较好,分发程序变得很容易。 结束语
    发表于 07-16 21:27

    【HZ-T536开发板免费体验】1 - 开箱测试

    这样的大模型了。 开机测试 开机启动后,可以看到相同是 Ubuntu 22.04.5 LTS (GNU/Linux 5.10.198 aarch64),不过不是桌面版本,所以如果直接将HDMI插入显示器
    发表于 07-16 19:41

    【HZ-RK3568开发板免费体验】合众HZ-RK3568开发环境搭建

    /gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin 保存退出 3.运行 source ~/.bashrc 让文件生效 $ source ~/.bashrc 交叉编译器验证 方法一:命令行下
    发表于 07-15 23:13

    ArkUI-X平台差异化

    : 1.自身业务逻辑不同平台本来就有差异; 2.OpenHarmony上调用了不支持跨平台的API,这就需要在OpenHarmony仍然调用对应API,其他
    发表于 06-10 23:08

    能在Meteor Lake平台上使用SDK 3.5吗?

    SDK 是 3.6 版,不支持 CYPD6127 部件。 那么,我能在 Meteor Lake 平台上使用 SDK 3.5 吗?
    发表于 05-26 08:01

    可以手动构建imx-gpu-viv吗?

    我是新手,希望能得到任何支持。 我目前正在使用内核 5.15 和 Yocto 4.0 (kirkstone)。我明白我必须为我的 aarch64
    发表于 03-28 06:35

    stm32F407平台上使用freertos,使用pvPortMalloc申请内存,发现内存中的数据总被修改,怎么解决?

    如题,我现在在stm32F407平台上打开FREERTOS,然后使用pvPortMalloc动态申请内存的时候,发现这块内存中的数据总是变化,后面改为malloc申请,内存中的数据就符合预期了,我已经按照网上的流程配置了freertos,不知道是什么原因导致这种现象?
    发表于 03-07 09:03

    【米尔RK3576开发板评测】+项目名称YOLOV5目标检测

    位置:cd Projects/rknn_model_zoo 进行编译:bash ./build-linux.sh -t rk3576 -a aarch64 -d yolov5 编译后生成的文件
    发表于 02-15 13:24

    E2000 Speedometer测试浏览器性能

    是完全开源的,这使其成为许多 Linux 用户的首选。下面以Chromium为目标对象,进行安装和测试E2000Q平台上的跑分。 方法 1:使用 APT 安装 Chromium apt命令是一个高级
    发表于 01-10 21:33