BOLT 二进制反馈优化技术

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 大型应用的代码往往达到数十甚至上百MB,这导致在程序执行时缓存机制无法充分利用,导致大量时间花费在CPU和内存链路上。通过对热点函数的布局进行优化,我们可以更好地利用CPU cache,从而获得较为可观的性能提升。针对这一问题,在编译技术上有PGO和Bolt两种解决办法,两者都是一种通过收集程序在运行时如跳转,调用关系,函数热度等执行信息,这些收集到的程序运行情况数据(profile data),可以更好地指导一些程序优化的策略,如是否对函数进行内联,以及对基本块和函数布局的排布来提高特定场景下的程序性能。

BOLT 二进制反馈优化技术

大型应用的代码往往达到数十甚至上百MB,这导致在程序执行时缓存机制无法充分利用,导致大量时间花费在CPU和内存链路上。通过对热点函数的布局进行优化,我们可以更好地利用CPU cache,从而获得较为可观的性能提升。针对这一问题,在编译技术上有PGO和Bolt两种解决办法,两者都是一种通过收集程序在运行时如跳转,调用关系,函数热度等执行信息,这些收集到的程序运行情况数据(profile data),可以更好地指导一些程序优化的策略,如是否对函数进行内联,以及对基本块和函数布局的排布来提高特定场景下的程序性能。

BOLT 的特点

PGO和Bolt两种方式都是基于收集到程序运行数据进行优化,但存在一定差异。不同于PGO通过编译器进行再次编译,Bolt是一个二进制优化和布局工具,直接对可执行文件/动态库ELF文件进行解析和进行修改,无需再次通过编译器进行构建。

image

image

在业务落地和优化结果方面,Bolt和PGO主要有以下两个方面的区别。

  1. Bolt在函数和基本块布局上能拿到更好的效果

编译器对函数的布局通常都是在编译优化的最后一步。在使用PGO的过程中,一个无法避免的问题就是函数内联等优化会导致上下文发生变化进而收集数据不准确,尤其是基本块排布需要的分支概率。而Bolt避免了callsite等信息的改动,专注于函数和函数内部的排布进行优化,可以得到更好的效果。

因此,Bolt和PGO在编译优化方法中并不是互斥的,是可以相互弥补的。在实践中,我们发现PGO和Bolt的优化在很多场景下是可以串联的,同时使用可以获得更好的性能收益。

image

  1. Bolt在有大型项目的部署会更加友好

这里的部署友好主要体现在三个方面,1) 更容易被集成到应用的构建系统中。Bolt在构建脚本中无需重复编译器的编译流程,这对于很多构建方式复杂的应用方来说构建修改更加友好,更方便落地。2)更快地构建速度。无需重复编译器流程也以为者通过Bolt进行优化能拿到比PGO更快的构建速度,比如编译器构建一次要20-30分钟的Clang使用Bolt只需要20~30秒。这对于单次编译就长达数小时的应用来说显然更容易接受。 3)Bolt可以对第三方的静态库进行优化。大型应用中往往很多第三方库的依赖,Bolt的好处之一就是可以其可以对静态链接进来的第三方库进行优化,而PGO则需要对第三方库逐个重新构建,在直接依赖于第三方静态库的场景中无法使用。

BOLT 在 Arm 当前现状

由于Bolt社区中,Arm后端当前只可以通过非LBR形式的运行时数据,数据无法记录函数调用关系和条件跳转指令上跳转发生的比率,因此Bolt后的结果相较X86差距较大

而通过coresight采样的数据有更精准的信息,我们能在倚天上获得同X86/LBR相同的精度,如跳转指令的起始和终止位置,以及函数间的调用。因此使用coresight采集出的数据能匹配到源代码中函数内的跳转发生方向和函数间的调用关系,对代码段进行重新布局提高热代码密度,降低I-cache/I-TLB miss进而优化程序性能表现。而非coresight的perf采样仅能获得函数及采样时pc相对于函数的偏移,无法满足反馈优化所需的信息。

image

其次,由于Arm后端尚不支持插桩的方式,当使用coresight数据时仍有不少bug,存在一定风险。 Alibaba Cloud Compiler对Bolt进行了集成,针对Arm和X86后端进行修复和优化,并在倚天上完成了多个项目的POC,目前在倚天上测试效果较Bolt on X86总体上有更好的性能提高。

image

目录
相关文章
|
2月前
|
存储 SQL 数据挖掘
TDengine 流计算与窗口机制的深度解析:揭示计数窗口的关键作用
在 TDengine 3.2.3.0 版本中,我们针对流式计算新增了计数窗口,进一步优化了流式数据处理的能力。本文将为大家解读流式计算与几大窗口的关系,并针对新增的计数窗口进行详细的介绍,帮助大家进一步了解 TDengine 流式计算,以便更好地进行应用。
51 1
|
4月前
|
消息中间件 Java Kafka
Kafka不重复消费的终极秘籍!解锁幂等性、偏移量、去重神器,让你的数据流稳如老狗,告别数据混乱时代!
【8月更文挑战第24天】Apache Kafka作为一款领先的分布式流处理平台,凭借其卓越的高吞吐量与低延迟特性,在大数据处理领域中占据重要地位。然而,在利用Kafka进行数据处理时,如何有效避免重复消费成为众多开发者关注的焦点。本文深入探讨了Kafka中可能出现重复消费的原因,并提出了四种实用的解决方案:利用消息偏移量手动控制消费进度;启用幂等性生产者确保消息不被重复发送;在消费者端实施去重机制;以及借助Kafka的事务支持实现精确的一次性处理。通过这些方法,开发者可根据不同的应用场景灵活选择最适合的策略,从而保障数据处理的准确性和一致性。
331 9
|
4月前
|
算法 数据处理 流计算
流计算引擎数据问题之传播模块工作如何解决
流计算引擎数据问题之传播模块工作如何解决
42 1
|
4月前
|
监控 Java API
【揭秘】如何用Flink CEP揪出那些偷偷摸摸连续登录失败的“捣蛋鬼”?——一场数据流中的侦探游戏
【8月更文挑战第26天】Flink 是一款先进的流处理框架,提供复杂事件处理(CEP)功能以识别实时数据流中的特定模式。CEP 在 Flink 中通过 `CEP` API 实现,支持基于模式匹配的事件检测。本文通过监测用户连续三次登录失败的具体案例介绍 Flink CEP 的工作原理与应用方法。首先创建 Flink 环境并定义数据源,接着利用 CEP 定义连续三次失败登录的模式,最后处理匹配结果并输出警报。Flink CEP 能够轻松扩展至更复杂的场景,如异常行为检测和交易欺诈检测等,有效应对多样化的业务需求。
51 0
|
4月前
|
消息中间件 Java 数据处理
揭秘Apache Flink的Exactly-Once神技:如何在数据流海中确保每条信息精准无误,不丢不重?
【8月更文挑战第26天】Apache Flink 是一款先进的流处理框架,其核心特性 Exactly-Once 语义保证了数据处理的精准无误。尤其在金融及电商等高要求场景下,该特性极为关键。本文深入解析 Flink 如何实现 Exactly-Once 语义:通过状态管理确保中间结果可靠存储;利用一致的检查点机制定期保存状态快照;以及通过精确的状态恢复避免数据重复处理或丢失。最后,提供一个 Java 示例,展示如何计算用户访问次数,并确保 Exactly-Once 语义的应用。
109 0
|
7月前
|
消息中间件 Java 调度
【深度挖掘RocketMQ底层源码】「底层源码挖掘系列」透彻剖析贯穿RocketMQ的消费者端的运行调度的流程(Pull模式)
【深度挖掘RocketMQ底层源码】「底层源码挖掘系列」透彻剖析贯穿RocketMQ的消费者端的运行调度的流程(Pull模式)
62 1
|
7月前
|
传感器 JSON Java
流计算中的流式图处理是什么?请解释其作用和常用操作。
流计算中的流式图处理是什么?请解释其作用和常用操作。
70 0
|
7月前
|
存储 运维 流计算
流计算中的容错机制是什么?请解释其作用和常用方法。
流计算中的容错机制是什么?请解释其作用和常用方法。
90 0
|
数据采集 消息中间件 监控
最终整体回顾(代码-离线计算)|学习笔记
快速学习最终整体回顾(代码-离线计算)
|
消息中间件 分布式计算 Kafka
【Flink】(九)状态一致性、端到端的精确一次(ecactly-once)保证1
【Flink】(九)状态一致性、端到端的精确一次(ecactly-once)保证1
321 0
【Flink】(九)状态一致性、端到端的精确一次(ecactly-once)保证1