字节跳动在PGO反馈优化技术上的探索与实践

news2024/11/22 17:17:18

背景

随着字节跳动的业务迅速增长,微服务的性能优化工作显得尤为重要,对于头部应用来说,提升若干百分点的性能也能为公司节省巨大的服务器资源成本。

编译器优化是软件性能优化的一种常用方法,相比其它特定的性能优化方法,它的适用性更广,能更全面地获得性能收益,从而降低成本。编译反馈优化(PGO)是常见的编译器的优化方法,字节跳动 STE 团队在编译反馈优化技术方向进行了持续的探索,并在字节跳动业务上积极地开展了实践工作,成功将编译反馈优化技术大规模落地于字节跳动业务,为公司节省了大量资源。

PGO简介

PGO(Profile-guided optimization)通常也叫做 FDO(Feedback-directed optimization),它是一种编译优化技术,它的原理是编译器使用程序的运行时 profiling 信息,生成更高质量的代码,从而提高程序的性能。

传统的编译器优化通常借助于程序的静态分析结果以及启发式规则实现,而在被提供了运行时的 profiling 信息后,编译器可以对应用进行更好的优化。通常来说编译反馈优化能获得 10%-15% 的性能收益,对于特定特征的应用(例如使用编译反馈优化 Clang本身)收益高达 30%。

编译反馈优化通常包括以下手段:

  1. Inlining,例如函数 A 频繁调用函数 B,B 函数相对小,则编译器会根据计算得出的 threshold 和 cost 选择是否将函数 B inline 到函数 A 中。
  2. ICP(Indirect call promotion),如果间接调用(Call Register)非常频繁地调用同一个被调用函数,则编译器会插入针对目标地址的比较和跳转指令。使得该被调用函数后续有了 inlining 和更多被优化机会,同时增加了 icache 的命中率,减少了分支预测的失败率。
  3. Register allocation,编译器能使用运行时数据做更好的寄存器分配。
  4. Basic block optimization,编译器能根据基本块的执行次数进行优化,将频繁执行的基本块放置在接近的位置,从而优化 data locality,减少访存开销。
  5. Size/speed optimization,编译器根据函数的运行时信息,对频繁执行的函数选择性能高于代码密度的优化策略。
  6. Function layout,类似于 Basic block optimization,编译器根据 Caller/Callee 的信息,将更容易在一条执行路径上的函数放在相同的段中。
  7. Condition branch optimization,编译器根据跳转信息,将更容易执行的分支放在比较指令之后,增加icache 命中率。
  8. Memory intrinsics,编译器根据 intrinsics 的调用频率选择是否将其展开,也能根据 intrinsics 接收的参数优化 memcpy 等 intrinsics 的实现。

编译器需要 profiling 信息对应用进行优化,profile 的获取通常有两种方式:

  • Instrumentation-based(基于插桩)
  • Sample-based(基于采样)

Instrumentation

Instrumentation-based PGO 的流程分为三步骤:

  • 编译器对程序源码插桩编译,生成插桩后的程序(instrumented program)。
  • 运行插桩后的程序,生成 profile 文件。
  • 编译器使用 profile 文件,再次对源码进行编译。

图片

Instrumentation-based PGO 对代码插桩包括:

1. 插入计数器(counter)

  • 对编译器 IR 计算 MST,计算频繁跳转的边,对不在 MST 上的边插入计数器,用于减少插桩代码对运行时性能的影响。
  • 在函数入口插入计数器。

2. 插入探针(probes)

  • 收集间接函数调用地址(indirect call addresses)。
  • 收集部分函数的参数值。

Sampling

Sample-based PGO 的流程同样分为三步骤:

  • 编译器对程序源码进行编译,生成带调试信息的程序(program with debug information)。
  • 运行带调试信息的程序,使用 profiler(例如linux perf)采集运行时的性能数据。
  • 编译器使用 profile 文件,再次对源码进行编译。

图片

其中步骤2采集的数据为二进制级别采样数据(例如 linux perf 使用 perf record 命令收集得到 perf.data 文件)。二进制采样数据通常包含的是程序的 PC 值,我们需要使用工具,读取被采样程序的调试信息(例如使用 AutoFDO 等工具),将程序的原始二进制采样数据生成程序源码行号对应的采样数据,提供给编译器使用。

探索与落地

对比 sampled-based PGO,Instrumentation-based PGO 的优点采集的性能数据较为准确,但繁琐的流程使其在字节跳动业务上难以大规模落地,主要原因有以下几点:

  • 应用二进制编译时间长,引入的额外编译流程影响了开发、版本发布的效率。
  • 产品迭代速度快,代码更新频繁,热点信息与应用瓶颈变化快。而 instrumented-based PGO 无法使用旧版本收集的 profile 数据编译新版本,需要频繁地使用插桩后的最新版本收集性能数据。
  • 插桩引入了额外的性能开销,这些性能开销会影响业务应用的性能特征,收集的 profile 不能准确地表示正常版本的性能特征,从而降低优化的效果,使得 instrumented-based PGO 的优点不再明显。

使用 Sample-based PGO 方案可以有效地解决以上问题:

  • 无需引入额外的编译流程,为程序添加额外的调试信息不会明显地降低编译效率。
  • Sample-based PGO 对过时的 profile 有一定的容忍性,不会对优化效果产生较大影响。
  • 采样引入的额外性能开销很小,可以忽略不计,不会对业务应用的性能特征造成影响。

我们的目标是在字节跳动业务上大规模落地 PGO 技术,使字节跳动大量的应用能够从 PGO 技术中受益。PGO 本身是一项较为成熟的编译器优化技术,我们面临的主要问题为如何简化 PGO 繁琐的流程,自动化数据采集与优化流程,保证优化的可靠性。我们设计了系统解决这些问题,该系统的架构如图所示:

图片

其中包含的主要任务有:

  • 集群维度的业务性能数据采集、维护与处理。
  • 业务二进制与调试信息维护。
  • 采样数据的查询与使用。
  • 生成编译器可用的信息(LLVM profile)。
  • Profile 更新,业务性能测试与发版上线。

数据采集与处理

我们做了大量的前期工作,在 SPEC CPU2017 等 benchmark 上进行了 PGO 测试与结果分析,基于测试结果得出结论,包括:不同采样事件以及 LBR 数据对 Profile 准确度的影响,单机采样频率与额外性能开销之间的联系,集群采样数据聚合策略以及样本数量与优化效果的联系等。

我们在字节跳动服务器集群的物理机实例中部署了采样程序,该程序在后台以用户无感知的方式进行着性能数据的常态化采集工作,并将采集的性能数据上传。原始数据被解析处理后,最终维护在采样数据库中。

对于每一条采样记录,我们会维护它的原始信息,以及额外的元数据,这些信息包括:

  • 采样地址
  • 采样的 LBR(last branch record)数据
  • 采样事件类型
  • 采样所属二进制的 ID
  • 采样业务的 PSM
  • 其它元数据

收集二进制与符号

我们搭建了二进制仓库,维护着所有线上运行的二进制以及其描述信息。对于加入到二进制仓库的二进制,系统会触发任务对其进行处理,提取 PGO 任务所需的符号信息,维护在指定的数据库中。

对于符号信息的查询,系统会返回指定二进制的 PC 值对应的 inline stack 信息,供 PGO 任务使用。

使用PGO优化流程

我们搭建了 PGO 平台,供业务用户使用 PGO 优化流程。业务接入 PGO 优化流程,首先需要通过平台指定策略。策略的作用是:

  • 指定目标业务的二进制以及使用场景等信息。
  • 指定生成 profile 需要的样本量以及时间窗口等信息。
  • 创建定时任务,为指定业务生成适用于 LLVM 的 PGO profile。定时任务会定时向采样数据库发送请求,查询目标二进制某一时间窗口内的性能数据,查询结果会被序列化。随后任务会解析采样数据以及相应的符号信息,生成 profile 文件,并将产物上传到指定存储中,供业务编译时使用。

Profile 文件会被策略定期更新,业务开发同学在构建时通过选项控制使用 profile 编译得到 PGO 优化后的二进制版本,进行常规的版本发布流程,性能对比测试,决定是否上线优化版本。

落地成果

我们在字节跳动内部头部 30+ 应用上落地了 PGO 优化流程,业务均获得明显的 CPU 以及延迟收益,平均获得了超过 5% 的 CPU 收益。

图片

总结

PGO 技术大规模在字节跳动业务落地实践后取得了显著收益,在其过程中,STE 团队也克服了诸多技术难题:完成了集群维度的数据采集工作,保证了数据的准确性同时做到了对业务无感知;在业务快速迭代的现状下,完成了二进制仓库的建设,规范了二进制符号信息的查询流程;搭建了 PGO 优化平台,简化了流程,业务方在构建程序时只需添加指定编译选项,大幅降低业务使用 PGO 的成本;在业务程序组成复杂依赖众多的现状下,分析预编译库的热点信息以及 PGO 效果不及预期的原因,推进了源码依赖的编译流程;同一个程序有可能被多个业务使用,在不同使用场景、时间段下,程序特征会有明显区别,我们在系统设计层面,有效地解决了该问题。

STE 团队会在后续的工作中完善已有系统,并对 PGO 技术进行持续的探索。包括支持 PGO 与 LTO 对业务的共同优化,在 PGO 平台引入 post-link time optimizer 对二进制进行优化,实现基于采样数据的软件预取优化等等,使字节跳动业务从中获得更大的受益。

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

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

相关文章

从零开始 Spring Cloud 11:Elasticsearch II

从零开始 Spring Cloud 11:Elasticsearch II 图源:laiketui.com 在上篇文章中我们学习了 es 的基本功能,在本篇文章中会学习 es 的一些高级功能,比如: 聚合查询自动补全集群部署 数据聚合 类型 **聚合&#xff08…

toB 业务分析

1、 如何透彻分析B端客户的需求? - 知乎我在讲《如何分析客户需求》这门课时,经常会问学员:“开发客户的最大困难是什么?”有人说价格高不好卖,有人说客户需求不好把握,有人说客户地处偏远,素养…

部署WMS仓储管理系统前要知道哪些关键点

随着物流行业的快速发展,WMS仓储管理系统解决方案已成为企业仓储管理的重要工具。然而,在部署WMS仓储管理系统之前,企业需要了解一些关键点,以确保系统的成功实施和高效运行。本文将介绍部署WMS前需要知道的关键点。 1、明确目标与…

一个小时入门 EJB

前置知识 在开始学习Java EE的Enterprise JavaBeans (EJB)之前,以下是一些你可能需要提前了解的技术和概念: Java基础:熟悉Java的基础知识,包括面向对象的概念(例如类、接口、继承和多态等)、基本的数据结…

【从零学习python 】27. Python 函数的使用及嵌套调用

文章目录 函数的文档说明1. 基本使用2. 高级使用 函数应用:打印图形和数学计算目标思考&实现1参考代码1 思考&实现2参考代码2 函数的嵌套调用进阶案例 函数的文档说明 1. 基本使用 def test(a, b):"用来完成对2个数求和" # 函数第一行写一个字…

产品需求管理软件:了解常见选择和功能

产品需求管理软件是一种非常重要的工具。它可以帮助企业更好地理解客户需求,提高产品开发效率并降低成本。本文将介绍一些常见的产品需求管理软件及其主要功能。 “产品需求管理软件有哪些?比较流行的有Zoho Projects、Trello、Asana、Smartsheet等。” …

「并发编程 」

一、 为什么会有线程安全问题 1)程序和CPU间的协作关系 CPU组成 寄存器 存储了从内存加载的数据(从内存中将数据加载到 L1,L2,L3 缓存,再到寄存器) ;寄存器的运行速度比内存快好多个级别&…

哈工大开源“活字”对话大模型

一、介绍 大规模语言模型(LLM)在自然语言处理的通用领域已取得了令人瞩目的成功。对于广泛的应用场景,这种技术展示了强大的潜力,学术界和工业界的兴趣也持续升温。哈工大自然语言处理研究所30余位老师和学生参与开发了通用对话大…

【BUG】docker安装nacos,浏览器却无法访问到页面

个人主页:金鳞踏雨 个人简介:大家好,我是金鳞,一个初出茅庐的Java小白 目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作 我的博客&am…

单链表相关操作(插入,删除,查找)

通过上一节我们知道顺序表的优点: 可随机存储(O(1)):查找速度快 存储密度高:每个结点只存放数据元素,而单链表除了存放数据元素之外,还需存储指向下一个节点的指针 http://t.csdn.cn/p7OQf …

计算机组成原理之浮点运算

1、浮点运算步骤 ①0操作数的检查,看有无简化操作的可能。 ②比较阶码大小并完成对阶(小阶向大阶对齐)。 ③尾数进行加或减运算。 (在进行尾数加减前,浮点运算器会自动把原码形式的尾数转换成补码形式。) ④…

像素相关知识

物理像素 指的是物理设备上真实的小方块个数,就是拿放大镜看屏幕时看到的像素点, 每个物理像素具体的大小是不固定的,不同设备不相同,由厂家设置 逻辑像素 指的就是我们css用到的px这个单位的像素 像素比(DPR&…

GB/GMP法规内容对沉降​菌、浮游菌监测​点设置相关规定及要求详解

微生物鉴定一直是生物、食品、医药等领域非常重要的监控指标,可以帮助预测药品生产过程以及无菌生产环境的风险。对于许多企业而言,建立厂房环境微生物菌种库对于微生物污染控制来说非常关键,环境菌种库的建立可以帮助制定洁净区消毒灭菌程序…

Leetcode40 组合之和2

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 解题思路:回溯剪枝 代码&#xff…

LeetCode--HOT100题(31)

目录 题目描述:25. K 个一组翻转链表(困难)题目接口解题思路代码 PS: 题目描述:25. K 个一组翻转链表(困难) 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表…

麦肯锡重磅发布2023年15项技术趋势,生成式AI首次入选,选对了就是风口

两位朋友在不同群里分享了同一份深度报告。 一位是LH美女,她在“AIGC时代”群里上传了这份文档,响应寥寥,可能是因为这些报告没有像八卦文那样容易带来冲击。 你看韩彬的这篇《金融妲己:基金公司女销售的瓜,一个比一个…

Ingress企业实战:金丝雀与蓝绿发布篇

背景 现如今,越来越多的应用采用了微服务架构,这也导致了应用数量相比传统模式更多,管理更加复杂,发布更加频繁,如果直接将新版本上线发布给全部用户。一旦遇到线上事故(或BUG),对用…

哪些客户适合打Cold Call?

都知道Cold Call是外贸营销中一种重要的销售方式,相比邮件跟进,它可以可实时交流,获取需求,解决问题,展示人情味,提升好感度,提高转化率。但由于陌生性,当下如果没有需求的话&#x…

“万恶”之源的KieServices,获取代码就一行,表面代码越少里面东西就越多,本以为就是个简单的工厂方法,没想到里面弯弯绕绕这么多东西

Drools用户手册看了得有一段时间了,现在开始看源码了,因为每次使用drools都会看见这么一段代码: 代码段1 起手代码 KieServices ks KieServices.Factory.get(); 那我就从这段代码出发开始研究drools的源码吧,这么一小段代码起初…

文件操作/IO

文件 文件是一种在硬盘上存储数据的方式,操作系统帮我们把硬盘的一些细节都封装起来了,程序员只需要了解文件相关的接口即可,相当于操作文件就是间接的操作硬盘了 硬盘用来存储数据,和内存相比硬盘的存储空间更大,访问…