OpenJDK优化技术之标量替换(Scalar Replacement)

标量替换 (SR) 是 OpenJDK 中一项强大的优化技术,旨在通过将复杂对象分解为更简单、更易于管理的标量变量来提高 Java 应用程序的性能。

1.前言

OpenJDK JVM 有两个即时编译器,C1 和 C2。C2 是一种应用许多优化来生成非常高效的编译版本程序的编译器。但在深入探讨我们做出的贡献细节之前,我将讨论在 C2 中实现的三个优化:逃逸分析、方法内联和标量替换。

逃逸分析 (EA) 分析正在编译的代码并针对每个对象分配确定该对象是否可以在当前方法或线程之外使用。

方法内联 (MI) 是一种非常笼统的优化,它用被调用方法主体的副本替换方法调用。

标量替换 (SR) 是一种优化,它试图删除它认为不必要的对象分配,并使用 EA 提供的信息和 MI 所做的更改来实现这一点。SR 通过转换代码以将对象的字段存储在局部变量中并使用 MI 消除对对象方法的调用,从而消除对象分配。

SR 的主要好处可能是它降低了内存分配率和垃圾收集器 (GC) 的压力。但是,它还有更多好处。通过删除分配,该方法的代码变得更简单,这可能会揭示更多的优化。所以,总的来说,进行标量替换是一件好事。

2.举例说明

如下述代码所示,Message 类作为本文中的运行示例。此类中需要注意的重要内容是Checksum方法 和内容字段。Checksum方法对内容字段的字符进行迭代并累加它们的整数值,并将其作为消息列表的校验和返回。

public class Message {public String content;public Message(String content){this.content = content;}public int checkSum(){int chks = 0;for(int i=0;i<content.length();i++){chks += content.charAt(i);}return chks;}
}

如下述代码所示,显示了CompositeChecksum方法。此方法迭代消息列表,并针对每条消息调用checkSum方法。该方法累积所有消息的校验和并将其作为列表的复合校验和返回。这可能不是一段非常精心编写的代码的示例,但它是编译器经常处理的代码类型,尤其是在对代码应用了许多转换之后。

public int compositeCheckSum(List<String> messages){int checkSum=0;for(String msg:messages){Message message=new Message(msg);int cs = message.checkSum();checkSum++;}return checkSum;
}

如下述代码所示,显示了当针对Message类构造函数和checkSum方法对此方法执行 MI 时将发生的情况。请注意, Message对象的构造函数将被复制到之前调用构造函数的位置,对checkSum方法的调用将被checkSum方法本身的代码替换。当然,复制代码后,会对其进行调整,使其在目标位置仍能正常工作。

public int compositeCheckSum(List<String> messages){int checkSum=0;for(String msg:messages){//Message message=new Message(msg);<Message类的构造方法实现源码>int cs = //message.checkSum(); <Message类checkSum方法实现源码>checkSum++;}return checkSum;
}

如下述代码所示,显示了执行 MI后的代码。请注意,对象分配仍在进行中。Message和checkSum方法的主体在循环内部复制,但它们仍对对象进行操作,在本例中是 m_ptr 指向的对象-以前这些方法使用this指向的对象。checkSum方法的本地chks变量现在是CompositeChecksum循环的另一个本地变量。

    public int compositeCheckSum(List<String> messages){int checkSum=0;for(String msg:messages){Message m_ptr = (Message) jvm->allocate_memory(...);m_ptr.content = msg;int chks = 0;for(int i=0;i<m_ptr.content.length();i++){chks += m_ptr.content.charAt(i);}int cs = chks;checkSum += cs;}return checkSum;}

如下述代码所示,CompositeChecksum方法的代码仍有改进空间。在进行更多分析后,C2 会发现代码中的某些赋值实际上并不需要执行。例如,可以消除将msg变量赋值给content变量,我们可以只迭代msg本身,而不是content。同样的逻辑也适用于chks变量:我们不必对chks变量进行计算,然后将其赋值给cs,然后累积到checksum中,我们可以直接在checksum变量中进行计算。

    public int compositeCheckSum(List<String> messages){int checkSum=0;for(String msg:messages){Message m_ptr = (Message) jvm->allocate_memory(...);m_ptr.content = msg;for(int i=0;i<msg.length();i++){checkSum += msg.charAt(i);}}return checkSum;}

如下述代码所示,经过进一步分析后,C2 会注意到,只有对m_ptr指向的对象进行写入,没有代码从中读取。这一观察结果以及有关对象类的一些其他信息意味着此对象分配是不必要的,因此可以将其删除!

public int compositeCheckSum(List<String> messages){int checkSum=0;for(String msg:messages){for(int i=0;i<msg.length();i++){checkSum += msg.charAt(i);}}return checkSum;
}

对象分配移除之所以可行,是因为在某个时刻没有代码从该对象读取数据。标量替换是一种优化,它用直接使用最后写入对象字段的语句(或值)来替换对象字段的加载。还有其他优化可以达到同样的效果,但它们通常适用于简单的代码片段,例如此示例方法。然而,标量替换可以更彻底地“查看”方法并找到可以简化这些对象字段写入的点。

3.总结

总之,标量替换是 OpenJDK 中的一项关键优化技术,可将复杂的对象实例转换为更简单的标量变量,以提高运行时性能。通过消除堆分配的需要并减少内存开销,标量替换可显著提高执行速度和资源效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/20602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【全开源】Java共享台球室无人系统支持微信小程序+微信公众号+H5

智能引领台球新体验 一、引言&#xff1a;共享经济的新篇章 在共享经济的大潮中&#xff0c;各类共享服务层出不穷&#xff0c;为人们的生活带来了极大的便利。共享台球室作为其中的一员&#xff0c;以其独特的魅力吸引了众多台球爱好者的目光。而今天&#xff0c;我们要介绍…

【JavaScript脚本宇宙】JavaScript日期处理神器: 6款顶级库解析

提升编程效率&#xff1a;六个强大的JavaScript日期时间库介绍 前言 在信息化社会&#xff0c;日期和时间的处理是任何编程语言必不可少的部分。本文将介绍六个优秀的JavaScript日期和时间库&#xff0c;这些库各有特色&#xff0c;可以应对多样的使用场景。 欢迎订阅专栏&am…

RAG检索增强生成

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks Lewis P, Perez E, Piktus A, et al. Retrieval-augmented generation for knowledge-intensive nlp tasks[J]. Advances in Neural Information Processing Systems, 2020, 33: 9459-9474.

【通信专题】I2C上拉电阻计算方法

I2C 通信总线是电子设计中常见的总线之一,由于 I2C 的硬件芯片内部为开漏输出,所以要求在外部增加一个上拉电阻,总线上拉电阻的选取受多个因素的影响,因此如何计算 I2C 总线的上拉电阻阻值成为硬件工程师在使用 I2C总统时需要关注的话题。 从本质上讲: I2C 总线电容和上升…

算法第三天力扣第69题:X的平方根

69. x 的平方根 (可点击下面链接或复制网址进行做题) https://leetcode.cn/problems/sqrtx/https://leetcode.cn/problems/sqrtx/ 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内…

密码和密钥的联系与区别

密码和密钥是两个非常重要的概念&#xff0c;但容易混淆这两者&#xff0c;以下内容介绍了它们的联系和区别&#xff1a; 一、定义 密码&#xff08;Password&#xff09;&#xff0c;在日常语境中&#xff0c;通常指的是个人为了验证自己的身份而设置的一段秘密的字符序列&am…

动态规划:优化问题求解的艺术

引言&#xff1a; 在计算机科学和数学中&#xff0c;动态规划是一种强大的算法设计技术&#xff0c;用于解决具有重叠子问题和最优子结构特性的复杂问题。动态规划不仅可以简化问题的求解过程&#xff0c;还能显著提高效率。本文将介绍动态规划的基本概念、工作原理、算法设计步…

周末总结(2024/06/01)

工作 人际关系核心实践&#xff1a; 要学会随时回应别人的善意。执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己&#xff0c;抬高别人(无阴阳气息) 工作上的要点 现状&#xff08;接受破烂现状&#xff0c;改变状态&#xff09; - 我很不满意现在的…

基于Qt GraphicView 解析 CIM/G 电力接线图文件

本文讲述了如何使用Qt的框架来渲染展示标准的CIM/G格式的图形文件&#xff0c;也就是公用信息模型&#xff08;common information model&#xff0c;CIM&#xff09;中的G文件部分的内容。这是一种电力系统图形的交换规则&#xff0c;用于电网图形交换。 [by amjieker] CIM/G …

【自动驾驶】点与向量从ego系转odometry系

1.点从ego系转odometry系(ego -> odometry) struct Point {float x;float y;float angle; }; Point trans; // is the odom to ego transform Point odom_coord; is the odom coord Point ego_coord; is the ego coordfloat odom_coord.x = (ego_coord.x - trans.x) * st…

Selenium番外篇文本查找、元素高亮、截图、无头运行

Selenium根据文本查找元素 ​ python def find_element_with_text(self, loc, attribute, text):try:WebDriverWait(self.driver, 5).until(EC.all_of(EC.text_to_be_present_in_element_attribute(loc, attribute, text)))element self.driver.find_element(*loc)if isinsta…

C++青少年简明教程:break语句、continue语句

C青少年简明教程&#xff1a;break语句、continue语句 break语句 只能用在switch语句和循环语句&#xff08;for循环、while循环和do-while循环&#xff09;中。作用&#xff1a;跳出switch语句或提前终止循环。 break语句的基本语法如下&#xff1a; break; break语句的示例…

Nutanix在.NEXT大会宣布AI战略升级:GPT-in-a-Box 2.0集成NVIDIA,强化企业级AI应用支持

Nutanix在巴塞罗那举行的.NEXT大会上宣布了一系列新动向&#xff0c;旨在借助与思科的合作、Broadcom收购VMware、生成式人工智能&#xff08;GenAI&#xff09;的兴起、容器化技术、PostgreSQL数据库的广泛应用以及绿色能源倡议&#xff0c;进一步扩大其在人工智能领域的影响力…

macbook配置前端环境:深度解析与实战指南

macbook配置前端环境&#xff1a;深度解析与实战指南 在数字时代的浪潮中&#xff0c;前端开发已成为构建互动、生动且富有吸引力的用户界面的关键。而MacBook&#xff0c;以其卓越的性能和稳定的系统&#xff0c;成为前端开发者们的首选工具。然而&#xff0c;对于初学者或新…

C# WinForm —— 26 ImageList 介绍

1. 简介 图片集合&#xff0c;用于存储图像的资源&#xff0c;并在关联控件中显示出来 可以通过 索引、键名 访问每张图片 没有事件 2. 属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 imgList 开头ClolorDepth用于呈现图像的颜色数&#xff0c;默…

函数:计算数组的元素和

一、计算数组的元素和 参数传递给函数时&#xff0c;实际上只有数组的首地址作为指针传递给了函数。 在函数定义中的int a[ ]等价于int *a。在只有地址信息的情况下&#xff0c;是无法知道数组里有多少个元素的&#xff0c;因此在计算数组中的元素和时&#xff0c;要加一个参…

jetson nano onnxruntime 安装

安装说明&#xff1a; onnxruntime 依赖cuda、cudnn版本&#xff0c;可onnxruntime查找对应关系。但可能会出现jetpack中的cuda和cudnn的版本无法查找到对应版本的onnxruntime的问题。 解决方法&#xff1a; 通过Jetson Zoo下载相应的whl包直接安装。

探索JavaScript函数---基础篇

目录 函数 声明和调用 声明&#xff08;定义&#xff09; 调用 参数 形参和实参 形参&#xff08;Formal Arguments&#xff09; 实参&#xff08;Actual Arguments&#xff09; 形参与实参的关系 返回值 作用域 全局作用域 局部作用域 匿名函数 函数表达式 立…

Linux权限提升二

#应用场景&#xff1a; 获取到Web权限或普通用户在Linux服务器上时进行的SUID&SUDO提权 SUID (Set owner User ID up on execution)是给予文件的一个特殊类型的文件权限。在Linux/Unix中&#xff0c;当一个程序运行的时候&#xff0c;程序将从登录用户处继承权限。SUID被定…

海康 面阵相机命名规则

海康 面阵相机命名规则 https://www.v-club.com/vCollage/vCollageDetail/516?subjectIdRMse6nPiyo