关于后端:大规模C编译性能优化系统OMAX介绍

4次阅读

共计 8687 个字符,预计需要花费 22 分钟才能阅读完成。

导读:本文摸索 & 钻研了大规模 C /C++ 服务编译性能优化相干技术,优化服务性能,升高机器老本,同时为了反对规模推广应用,升高业务线接入老本,保障优化成果,进行面向云上微服务,发展平台化优化服务零碎 OMAX 建设,并在百度举荐零碎上大规模利用,获得线上服务 CPU 性能优化 10%+ 和上线速度晋升 40%+ 双收益,优化后服务运行稳固,性能收益继续。

全文 11509 字,预计浏览工夫 29 分钟。

一、背景

随着大型互联网公司的业务一直倒退,后端 C ++ 模块的逻辑解决越来越简单,且参加开发人员泛滥,代码品质参差不齐,服务面临性能一直进化危险,大型程序模块,常见的通过代码上优化,次要存在以下问题:

  • 老本高:典型举荐业务服务海量代码,逻辑性能简单,有的往往须要深刻了解业务进行优化,优化门槛高
  • 效率低:模块迭代频繁,定向优化,没有肯定的通用性和可持续性,往往随着迭代优化逐步隐没劣势,须要一直周而复始投入发展优化

二、编译优化技术简介

编译优化技术,次要通过编译器或者优化工具框架来优化改写代码实现,实现性能晋升,同时保障和未优化时性能上统一,对于代码开发者通明,这样可升高人工代码优化老本,晋升优化效率,且可继续解决一类性能问题。

目前编译性能优化技术,依照编译过程来划分,次要有编译期,链接期和编译后的优化,上面简要介绍下这些优化技术特点,应用形式和优化成果等状况。

2.1 编译期

  • 根底参数优化

在程序编译期间进行的优化,次要是基于编译器提供的能力,在不同的场景,综合编译工夫,编译产出体积大小、性能优化幅度和 CPU 硬件反对等衡量抉择最合适的优化参数,各参数优化汇总如下表:

优化成果:

通过测试程序(排序算法),验证下参数类优化成果,测试 O3 优化状况下,相比没有开优化形式,解决性能晋升 49%,可见参数优化简略无效。

  • PGO 反馈编译优化技术

FDO/AutoFDO

通过收集程序性能优化数据,编译期间联合该性能反馈数据,领导编译器进行精准优化,产出优化程序过程,依据收集性能数据形式,次要蕴含以下两种优化技术:

优化步骤:

FDO

1. 插桩版本编译:首先编译非凡的插桩版本,这个用于采集性能数据

gcc test.c -o test_instrumented -fprofile-generate

2. 数据采集:运行插桩版本的程序,程序退出后产出收集的数据 test.gcda

./test_instrumented

3. 编译优化:数据采集实现后,编译器基于该数据在编译器进行再次编译优化

gcc -O3 test.c -o test_fdo -fprofile-use=test.gcda

AutoFDO

1. 数据采集:通过 perf 工具收集运行时的程序,产出性能数据 perf.data

perf record -b -e br_inst_retired.near_taken:pp -- ./test

2. 数据转换:联合程序,将 perf.data 性能数据,转换为函数信息,供后续编译器优化应用

create_gcov --binary=./test --profile=perf.data --gcov=test.gcov -gcov_version=1

3. 编译优化:gcov 数据筹备好了,编译器基于此数据发展编译器的优化

gcc -O3 -fauto-profile=test.gcov test.c -o test_autofdo

优化成果:

通过测试程序,测试 FDO 和 AutoFDO 优化的解决性能,绝对比 O3 根底上,FDO 性能晋升 11.4%,AutoFDO 性能晋升 11.5%,能够见反馈优化还能进一步晋升可观的性能。

2.2 链接期

LTO

编译器在 link 阶段进行的优化,因为在编译尾部阶段,可能获取全副的 object 文件,这样能够以全局视角进行优化,进一步优化晋升性能,目前次要有以下几种,GCC 编译器 >=4.7, TinLTO Clang 编译器

次要优化项:

优化成果:

通过测试程序,退出 -flto 优化,绝对 O3 根底上,发现有 8% 左右性能晋升

2.3 链接后

BOLT

Facebook 最新开源的链接后的反馈优化技术, 基于 LLVM 根底框架开发,目前已合入 llvm-project 作为其一部分,在其公司外部服务和大型 C ++ 程序 Clang & GCC 实际验证,采纳反馈数据领导框架优化程序技术,执行程序 bin + 反馈 profile 数据进行优化,优化产出新的 bin,目前反对次要的 X86-64 and AArch64 ELF 程序格局。

次要特点:

  1. 对程序和 GCC 编译器版本要求低
  2. 采纳 perf 收集性能数据,可在生产和测试环境生产优化数据,对服务影响低
  3. 个别的大型程序(40w+)优化速度快,理论优化过程均匀 4 -5min,优于 FDO/AutoFDO 优化时长(15min+)

次要优化项:

优化步骤:

1. 数据采集

通过 perf 工具采集程序运行时 CPU LBR (branch information)事件,可通过采样频率和工夫管制采集肯定指令数 (>=1B 指令) 的数据 perf.data,供后续优化应用。

# 十分驻服务
perf record -e cycles:u -j any,u -o perf.data -- <executable> <args> ...
#常驻服务
perf record -F <frequency>  -e cycles:u  -o  perf.data  -j any,u -a -p <pid> -- sleep <time_length>

主要参数阐明:

-F <frequency> 采样频率

-o perf.data 输入采样文件

-p <pid> 程序过程 pid

— sleep <time\_length> 采样时长,单位秒

2. 数据转换

perf.data 采集好之后,应用 bolt 框架工具 perf2bolt 进行优化数据格式转换

perf2bolt -p perf.data -o perf.fdata <executable>

3. 优化解决

perf.fdata 优化数据筹备好之后,应用 bolt 框架工具 llvm-bolt 进行程序优化,产出 <executable>.bolt 程序

llvm-bolt -enable-bat=1 <executable> -o <executable>.bolt -data perf.fdata  -align-macro-fusion=all  -reorder-blocks=cache+ -reorder-functions=hfsort+ -split-functions=3 -split-all-cold -split-eh -dyno-stats -icf=1 -update-debug-sections

主要参数阐明:

-enable-bat=1 反对 bolt 优化程序再次循环优化

-reorder-functions=hfsort+ 反对多种算法抉择

-dyno-stats 指令优化统计输入

-update-debug-sections debug 版本

优化成果:

Facebook 数据中心服务,BOLT 利用实现了高达 7.0% 的性能减速。开源的程序 GCC 和 Clang 编译器测试,评估表明,BOLT 在 FDO 和 LTO 的根底上将程序的处理速度进步了 20.4%,如果程序在构建时没有 FDO 和 LTO,则速度将进步 52.1%

通过测试程序比照,应用 BOLT 优化,比照 O3 优化晋升 18% 性能。


三、整体技术架构计划

基于以上的编译优化技术,大规模 C ++ 零碎上实际落地,面临一些问题 & 挑战。

  • 接入老本:外部零碎有大量微服务模块,代码版本和编译参数不一,开源技术至工程可实际问题,反馈优化技术数据如何收集和保护,如何高效反对简单模块的低成本接入问题;
  • 优化速度:业务迭代频繁,如何在不影响变更上线效率前提下,保障优化成果,反对高效优化。

通过摸索钻研编译全流程相干的优化技术,设计通用的全流程优化解决方案,反对多种优化技术组合优化,指标实现优化成果最大化,满足多场景业务需要。

平台优化整体架构,见图 1,次要包含用户接入,优化零碎和数据系统,实现从业务接入至优化产出过程闭环解决,升高业务接入老本,晋升优化效率。

△图____1 omax 性能优化零碎架构

3.1 用户接入

通过插件化形式接入后端优化服务,实现前端轻量级接入,后端简单外部解决逻辑对业务通明,同时凋谢 API 形式兼顾其它场景接入。

3.1.1 流水线插件

百度内流水线式流程工作解决平台插件:基于现有流水线凋谢能力,开发优化接入插件,公布至公共插件核心供各业务线接入应用

__△图____2 流水线 pipeline 接入优化插件__

次要能力:

  1. 独立建设优化阶段:接入阶段见图 2,作为流水线一个阶段插入,将所有的优化收敛到此阶段,整体反对灵便动静热插拔,性能开启和敞开可一键管制。
  2. 外围多产品优化机制:多产品概念,次要是这样一种开发和上线模式,基于同一套代码库,通过派生生成不同的配置,实现不同服务性能,广泛应用于不同的产品需要中,晋升架构 & 代码能力复用。如何优化此类常见的迭代模式,设计基于流水线的多产品优化机制,用于一条流水线,兼容优化每个产品的产出,并保障各自的优化版本部署隔离管制。

△图 3 多产品优化机制

多产品机制见图 3,次要由基于流水线工作解决的前端各插件,omax 优化插件, 测试工作,公布插件,上线插件等,联动后端优化零碎 omax-server,上线零碎,产品库等,通过惟一产品标识(流水线名 + 产品),串联该产品的优化,公布和上线相干解决流程。

1)产品抉择阶段:通过列表形式抉择,反对默认形式(提供抉择不做优化),字段须要惟一,实际中咱们以 app 上线模板名称为标识,后续阶段依赖此抉择,做进一步串联解决。

2)优化插件解决阶段:插件将产品 & 流水线信息传递至后端服务,通过产品信息获取对应的优化数据,进行优化解决,并公布至产品库,返回公布地址至插件端失效,供后续测试和公布阶段解决。

3)测试 & 准入阶段:依据产品标识信息,抉择相应的词表和测试策略,进行服务的性能、性能和稳定性测试。

4)公布阶段:设计防进化机制,该阶段将优化的惟一 tag 信息写入产品库产品的 meta 信息中,标记为优化版本,通过与上线平台 tower 制订校验规定,保障优化版本匹配上线,避免上线平台误选未优化或者其它产品版本上线,导致性能进化。

5)上线阶段:在流水线上线阶段,如果产品标识和上线模板匹配,不必再次抉择上线模板,间接跳过抉择模板过程发单上线,简化上线流程。

3.1.2 API 接入

流水线之外,还提供原生的 API 接入,反对其它场景的接入需要,如编译和线下测试平台等,次要蕴含接口:触发工作的执行,查问当前任务状态,勾销以后正在执行的工作等接口,通过 HTTP 形式,携带注册认证信息,与后端优化服务进行交互。

3.2 优化零碎

优化零碎作为服务提供者,反对优化的高效运行,次要从这几个方面来设计思考:

  • 动静弹性扩大:分布式任务调度运行框架设计,反对资源横向扩大,解决多任务处理负载问题,反对云上部署;
  • 疾速开发框架:通过设计分层的开发架构机制,将架构和业务性能解耦,业务开发反对 python 和 shell 等脚本语言形式,实现测试同学也能疾速动手开发,升高开发门槛,晋升对业务疾速适配能力。

优化零碎次要蕴含以下几个外围局部:

  • Webserver 是 OMax 零碎后端 server 的入口,次要性能是解析申请参数,并对一些参数配置进行 DB (数据库)读取或写入操作,最初将蕴含 Worker 所需残缺参数的申请转发给 TaskManager。
  • TaskManager 是一个分布式任务调度零碎,反对多任务并行处理、动静横向扩缩容,通过 webserver 对外提供服务入口,TaskManager 接管到 webserver 的申请后会调配一个 Worker 来解决具体业务;
  • Worker 是具体业务的理论执行者,它由 dispatcher 和工作执行单元组成,dispatcher 根据申请参数的不同,将不同申请散发到不同的工作执行单元上,工作执行单元反对横向或纵向扩大,能够疾速接入新的业务需要,打算的工作执行单元有性能优化,公布,优化数据格式转换、监控和定时工作等。

3.3 数据系统

数据系统承当对所有优化工作的数据供应性能,数据的稳固,精确与否间接影响性能的优化状况,所有数据系统的设计上次要从数据准确性,产出能力,数据管理能力等方面思考,发展相应的建设。

数据系统次要由采集端模块 Sample、数据转换、数据管理等几局部形成。通过在实例粒度上部署采集 Sample (十分驻过程,没有采集工作时不耗费任何资源),将采集到的数据传输到存储服务,近程采集的具体实例、采集周期以及采集工夫点都由工作中控管制,并且反对不同服务的个性化配置,而后数据转换工作进行 perf 数据至 profile 优化数据格式转换,最终对数据打上版本信息,存储入库,供优化工作拉取解决。外围次要包含以下三局部:

  • 数据采集:线上数据 + 线下数据(结构 + 引流),满足全方位的数据需要,反对多场景业务;
  • 数据转换:实时 + 例行转换,兼顾性能、效率和资源耗费,笼罩全场景业务
  • 数据管理:数据版本治理,反对数据按版本优化,同时满足异样时回滚需要,晋升优化兼容能力。

3.4 零碎报警监控机制

整个优化服务的安稳运行,离不开欠缺的监控报警机制,通过本身架构工作散发机制和解决能力,建设自闭环的监控机制,辅助机器人巡检能力,及时感知优化和数据的异样解决状况,不便运维及时进行相干的异样排查解决,保障系统稳固运行。次要从以下三个外围方面,保障优化零碎的服务质量。

  • 数据规模:例行的数据采集规模覆盖度监控工作,保障优化精度,天级汇总优化数据生产和优化解决运行状况,音讯群和邮件告诉;
  • 指令数笼罩:优化规模指令数有余拦挡机制;
  • 工作异样:架构通过惟一 ID 标识工作运行标识,两头处理过程可追溯,异样时音讯群和邮件及时告诉。

四、关键技术

4.1 组合叠加优化

通过在优化的编译期,链接期和链接后三个阶段,各种采纳相应的优化技术,综合叠加优化,实现最大化的优化成果,流水线次要优化过程见图 4。

_____△图 4_____ 组合叠加优化

4.1.1 编译期

  • 根底参数优化

工程实际

1. 优化参数抉择:

O 系列: 生产环境次要应用 -O3 优化,开发调试应用 -Og 形式,保障调试体验下具备肯定的性能晋升。

CPU 指令集:通过 cpu- z 工具获取反对的 CPU 型号,可抉择应用开启编译指令 mmx, sse, avx 的程序版本。

代码生成:动态库 fno-pic,目前存在不少动态库依赖库应用 fpic 场景,进行编译适配,晋升整体性能。

2. 最大化优化成果:

大型服务次要由主模块 + 依赖模块形成,独立功能模块便于代码间复用,晋升程序健壮性和开发效率,然而参数优化个别只在主模块配置,这样依赖模块不失效,影响整体优化成果。

通过联结编译平台,实现全局参数配置失效编译形式,将优化参数携带到所有模块参加编译,如 GO3 开启全局 03 优化, 实现全模块优化成果。

  • PGO 反馈编译优化技术 -FDO/AutoFDO

工程实际:

1.FDO

应用程序要求:目前随程序启动常驻线程较多,大多没有退出解决,有的次要通过 \_exit(0)等形式退出,因为优化数据产出依赖程序优雅退出,所以须要对程序启动的线程做退出解决。

编译器要求:倡议 GCC>=8.2 以上,编译要求两次编译代码及其依赖版本保持一致。

2.AutoFDO

应用程序要求:理论大型程序编译,波及依赖模块泛滥,有的以编译好的.a 或 so 模式引入,这样参加编译优化时,存在一些编译优化失败,倡议尽量源码模式参加编译,晋升优化覆盖面,缩小异样编译优化谬误。

编译器要求:倡议 GCC>=8.2 以上。

4.1.2 链接期

LTO

工程实际:

应用程序要求:接入简略,编译时增加链接参数 -flto 参数即可,针对 FDO 编译增加 ”-fprofile-correction” 选项纠正多线程收集的数据一致性问题;

编译器要求:倡议 GCC>=8.2 以上,绝对 gcc ld 链接器,晋升优化速度可应用 llvm 的 lld link 器替换。

4.1.3 链接后

BOLT

工程实际

1. 利用适配:对于 GCC8 增加编译参数 -freorder-blocks-and-partition,对依赖模块尽量要求以源码形式参加编译,如果存在对应库优化失败,通过增加编译参数从新编译即可。

2. 开源 BOLT 工具深度优化革新:从开源至实际面临一些可用性和易用性问题,咱们通过钻研框架,发展深刻革新,以满足工程实际要求,次要包含以下外围方面。

  • 反对 >=10G 以上优化数据处理,晋升对海量数据的适配,满足大量规模服务数据优化需要
  • 优化对 perf 采集的大数据量 >=5G+ 至优化 profile 数据格式解析,并行化革新解决,晋升优化速度
  • 欠缺要害优化门路调试信息,不便疾速调试和定位优化失败问题,解决依赖兼容高效定位问题

3. 线上环境数据采集适配

  • perf 对采集 CPU 硬件事件反对,通过机器失效以下配置,反对次要的 lbr 事件采集
1. 批改不重启机器,立刻失效:echo -1 > /proc/sys/kernel/perf_event_paranoid
2. 设置永恒失效(避免机器重启生效)/etc/sysctl.conf
kernel.perf_event_paranoid = -1
3. 晋升软限大小设置
/etc/security/limits.conf
*soft nofile 65535
*hard nofile 65535
  • 规模数据采集验证

统计机器 CPU 型号,依照类型收集采样数据,测试不同型号和及其合并后,采样数据和热点函数对应状况

4.2 异步 + 同步优化模式

异步优化, 兼容性能和优化速度,晋升实际落地可用性,满足大部分业务高频迭代场景的需要, 见图 5,次要蕴含以下几个局部:

  • 解耦反馈优化数据产出和优化过程应用,优化和数据筹备独立发展,通过数据援用关联,晋升优化速度(40min->5min)
  • 线上生产环境 + 规模批量收集数据,晋升优化的准确性,解决采样概率上的失落和笼罩有余问题,晋升优化成果
  • 优化数据定时和例行同步生产,一直靠近同步优化的成果,晋升优化成果

此外流水线场景下,还反对同步优化,并给异步奉献优化数据,满足实际中实时优化的需要,谋求最大优化

△图 5 omax 高效性能优化模式

4.3 疾速上线

在获得最大性能优化的同时,还能够通过 release 和 debug 优化模式,优化缩减程序 bin 体积大小,晋升上线时候部署速度,通过建设疾速上线机制,实现业务疾速接入,见图 6。

  • omax 后盾优化服务,扩大反对两种 release 和 debug 版本优化产出,优化缩减体积大小,同时反对异样 core 时 debug 信息查看;
  • 反对通用的 strip 裁剪模式,实现一般未应用优化服务,也都可接入应用疾速上线能力;
  • release 和 debug 版本建设版本映射,线上服务应用 release,查 core 拉取对应 debug 版本解析。

次要处理过程:

疾速上线:上线公布产出时,反对同时产出 debug 和 release 版本,两者建设映射关系,通过 release 优化公布包中增加 debug-meta 的信息,用于线上异样 core 时,拉取 debug 版本, 应用 gdb 查看堆栈和函数信息。

一键 debug:提供 debug 版本快捷拉取机制,因为 debug 版本体积较大,对于线上场景胜利拉取后,依据登录和超时状态,实现 debug 文件主动清理登场,保障线上环境平安。

△图 6 疾速上线和简化查 core 机制

4.4 性能数据仓库

基于线上性能采集数据通路和反馈数据技术应用到的 profile 性能数据,建设长期可记录、可追踪的性能进化剖析数据仓库,见图 7,用于进一步性能优化剖析,领导代码改良优化,次要蕴含以下局部。

  • perf 性能优化数据热点剖析,领导代码层面的剖析优化;
  • 程序调用 cpu 火焰图 & 指令 miss 数据,用于发现和优化程序热点调用函数栈问题
  • mem 指令 miss 数据,用于剖析内存性能问题。

△图 7 线上服务性能数据仓库机制


五、落地 & 收益状况

目前该平台在百度外围举荐零碎全面落地,笼罩举荐零碎所有次要模块,优化云上微服务容器数万级以上,实现 CPU 优化 10%+,时延升高 5%+,上线速度晋升 40%+,公布包大小缩小 10 倍 +,服务运行稳固,性能收益继续,无力撑持服务大量的优化需要,降本增效,撑持业务高速倒退。

作为后续,本我的项目也在一直摸索大规模 C ++ 服务开发的最佳实际,也欢送志同道合者独特探讨。

六、参考资料

【1】Maksim Panchenko, Rafael Auler, Bill Nell, Guilherme Ottoni. BOLT: A Practical Binary Optimizerfor Data Centers and Beyond. Facebook, Inc.

【2】Dehao Chen,David Xinliang Li,Tipp Moseley. AutoFDO: Automatic Feedback-DirectedOptimization for Warehouse-Scale Applications. Google Inc.

【3】https://github.com/facebookin…

【4】https://github.com/google/aut…

【5】https://github.com/VictorRodr…\_tutorial

【6】https://gcc.gnu.org/wiki/Auto…

【7】https://clang.llvm.org/docs/T…

【8】https://gcc.gnu.org/onlinedoc…

举荐浏览

挪动端异构运算技术 -GPU OpenCL 编程(根底篇)

云原生赋能开发测试

基于 Saga 的分布式事务调度落地

Spark 离线开发框架设计与实现

爱番番微前端框架落地实际

正文完
 0