本文收拾自 2024 年 4 月 QCon 全球软件开发大会(北京站) 功能优化专题的同名主题共享。
当时数据中心的服务器中布置着各类 CPU(Intel/AMD/Ampere 等),这些渠道的差异,使得运转在上面的程序无法保证始终运转在最佳状态,成为了提高事务效能的一大阻止。
CPU 功能调优,这不只要求工程师对各个渠道有着深化的理解,一起需求掌握各类功能剖析东西和办法,并依据得到的观测数据,归纳诊断出真实的瓶颈原因,并据此打开优化操作,终究提高事务体现。
这种传统的 CPU 功能调优办法,对工程师的能力和经历都有着不小的门槛,难以在更大规划规模地普及,使得许多客户对体现不理想的程序束手无策。
百度智能云推出的一键调优套件 Btune,完成了整个 CPU 功能调优进程的一键自动化,使得用户能够快速完结瓶颈定位,完成功能优化。
今天我的演讲内容分三个部分:多元 CPU 功能调优的技能应战;Btune 一键调优产品设计计划;百度智能云的调优实践。
1 多元 CPU 功能调优的技能应战
跟着 AMD/ARM 的 CPU 在数据中心处理器鼓起,服务器范畴 CPU 近几年出现多元化开展,Intel/AMD/ARM 并存的趋势。
首要,Intel 仍然是数据中心 CPU 的干流,从 12 年开端的 E5 系列到现在最新的 GNR。
从 17 年开端,AMD 的 Naples 和 Rome 开端进入数据中心范畴。到了 21 年,Milan 处理器以其多核优势开端在数据中心大规划上量。
从 21 年开端,Ampere 的数据中心处理器,由于它比照同期其他架构处理器的性价比优势,在数据中心开端占有一席之地。
百度智能云也是 CPU 多元化趋势里边的先行者,以及大规划实践者。
从 2017 年至今先后引入 4 代 AMD 处理器。从 2018 年开端大规划试点 AMD 落地数据库等存储场景开端,之后的每一代 AMD 处理器都有相应的核算产品推出。
从 2022 年至今,先后引入 2 代 ARM 处理器。自 22 年开端,百度内部干流通用核算场景(包括查找、引荐、商业、大数据等)都现已规划运用了 ARM 处理器。23 年,百度智能云在国内初次发布了 ARM 虚拟硬件产品 AVH。今年,咱们在业内初次将 ARM 服务器大规划应用于智驾仿真场景,并根据 ARM 服务器对外推出了车云同构的仿真计划。
那么在 CPU 多元化的当下,怎么进行跨渠道功能调优呢?接下来咱们从不同层面来看一下。
首要看下 Core 层面。
咱们知道,影响 CPU 功能的不只是 CPU 的频率和核心数,还有指令和微架构。
咱们以 Intel/AMD/Ampere 三家 CPU 比照能够看到:
SIMD 指令方面:Intel 从 21 年的 Ice Lake 开端就现已支撑 AVX512 指令了,截止现在 AMD 一直是 AVX256,直到未来的 Zen4 架构才开端支撑 AVX512,Ampere 现在的 Altra 包括最新一代 OneX,都是 128 位宽的 Neon 指令。在一些大位宽并行核算场景,Ampere 相对 Intel 和 AMD 要弱一些。
浮点指令方面:三家对 BF16/FP16 的支撑是不一样的,渠道是否支撑 BF16 或者 FP16,在模型进行 16 bit 量化的时分功能差异很大,在 AI 推理场景 BF16/FP16 的支撑是个要特别注意的地方。
频率与 HT 方面:Ampere 是固定频率,不支撑 HT,独立的物理核,在云原生场景有优势。Intel 和 AMD 都能够超频,可是有一些差异,Intel 是 all core boost,AMD 的不是 all core boost,这个在一些对频率敏感的场景需求特别关注。
Socket 层面。
SubNUMA 方面,由于 Intel/AMD/Ampere 三者的架构不一样,Intel 是 mesh 架构,AMD 是多 die 多 NUMA 架构,Ampere 是单 die 多 NUMA架构。AMD 和 Ampere 有subNUMA的差异,而且能够看到 AMD 在 subNUMA 内和 subNUMA 间的延时不同要更显着一些。这就导致在一些场景,AMD 做 subNUMA 亲和战略对事务功能会有较大提高。
L3 Cache 方面,Intel/AMD/Ampere 三者的容量和延时都有很大不同,全体来看 Ampere 的 L3 无论容量还是延时功能要差一些。
这儿特别提一下 CPM。Ampere 有一个 CPM 的差异,CPM 内的 Core 间通讯比 CPM 之间的要小许多,这就导致在一些场景 CPM 亲和战略对 Ampere 机器会有较大的功能提高。
在互联层面。
Intel/AMD/Ampere 选用的是不同的互联协议。
Ampere 选用的开源 CCIX 协议,这个协议的访存延时和 DMA 读带宽,相比另外两种协议要差许多。所以 Ampere 服务器在许多应用场景,是否支撑跨路访问对功能影响非常大,需求特别针对跨路访问进行规避。
AMD 的 xGMI 协议,跨路 DMA 读带宽要更大,在一些大内存带宽的场景(比方 EDA 仿真),体现会比较好。
内核层。
这儿列举了 4 个比方。
第一个比方是 CPM 亲和。这个问题能够经过内核 patch 进行调度层的 CPM 亲和性优化。当然假设不放到内核层面处理,也能够在用户层面做特别的绑核逻辑以到达亲和的目的。
第二个比方是 page cache 亲和。内核里边默许是从容器地点 NUMA 来分配 page cache 内存区域。假设容器在 node0 运转,磁盘链接在 node1,就会导致磁盘的 I/O 要从 node1 跨路 DMA 到 node0 的内存区域,这样在跨路延时大的机器上,I/O 功能就会下降许多。
第三个比方是页表办理,在许多事务场景,64K 页面功能要比 4K 页面功能好。但一起大页表也会导致一些事务内存容量占用添加。两者之间的挑选需求进行归纳考虑。
第四个比方是中止绑定,内核是优先从中止绑定 NUMA 来分配 skb_buffer。假设中止绑定到 node1,网卡链接在 node0,网络数据就需求从 node0 跨路 DMA 到 node1 地点内存区域,这样在跨路延时大的机器上,网络功能就会下降。
Runtime 层面。
不同渠道的底层加快指令是不同的。首要 ARM 和 x86 是不同的指令集,其次即便相同是 x86 指令集的 Intel 和 AMD,他们在一些加快指令层面也有差异。
一个应用程序针对渠道的指令加快优化,首要能够经过两个环节进行:一个是编译层面的优化;一个是 runtime 层面的优化。
咱们把 runtime 差异成了 3 个方面。
第一个是体系基础运转时库。不同版别的运转时库,在有些场景功能差异会非常大,一般来说版别越高功能越好。
第二个是各渠道厂商自己供给的专有加快库。为了提高竞争力和壁垒,芯片厂商都会有一些针对自己芯片的加快库,比方 Intel 有自己的 mkl 等库,AMD 有自己的 aocl 等库。这类库有两个问题:库和渠道厂商是绑定的,比方相同的压缩操作接口不一致;另外有些库即便能够多渠道运转,可是其功能不同会比较大,比方 mkl 库相同的操作在 Intel 渠道功能发挥的比较好,到 AMD 渠道尽管也能运转,可是由于 mkl 库不会启用 AMD 芯片的许多加快特性,这就导致其功能就会差许多。在跨渠道之间进行搬迁时分,会遇到相应的功能问题。
第三个是一些高级言语的运转时,如 JDK/Ruby/Python 等。这类运转时除了渠道无关的战略优化外(比方 JDK 的 GC 战略、热门运转时编译战略等),针对渠道还能够进行许多指令层面的加快优化。
应用层。
这儿举了 4 个比方,都是相同的程序往不同渠道搬迁进程中,遇到的功能问题。
第一个是 BRPC 的比方,咱们将一个 BRPC 服务从 x86 搬迁到 Ampere 后,发现其 CPU 利用率比 x86 高近一倍。这儿的原因便是由于 Ampere 跨路延时高,导致线程切换慢,这个经过调整 BRPC 的协程切换形式后问题得到了处理。
第二个比方是混部冲突。跟着节点算力越来越大,单节点能够布置的任务数越来越多,这个会带来许多层面的功能应战。比方:sys_use 增高、容器监控组件卡死、内核争抢严重、lsof/ps 慢等功能问题。
第三个比方是 Spinlock 锁。x86 渠道和 ARM 渠道在底层完成机制上有不同。x86 支撑 HT,底层经过 pause 指令完成,只让出 HT 核算单元而不释放 CPU。ARM 物理核需求经过 yield 指令完成,有些程序默许运用的 wfe 指令会带来唤醒延时。延时敏感作业需求注意这个不同。
第四个比方是编译。在编译适配环节,程序需求面向不同渠道进行优化。比方编译器层面,不同渠道需求不同的编译设置才干充分发挥渠道功能。基础库层面,不同渠道有不同的优化版别。汇编指令层面,有一些程序会直接调用汇编指令进行并行加快,这时分针对不同渠道需求进行指令调用层面的优化。
全体来看,功能优化的应战是多维度的,从硬件层、体系层、runtime 层到应用层,每一层都需求充分优化。
面临多维度功能应战,怎么充分发挥 CPU 功能,保证 SLA 是一个很有应战的事情。
2 Btune 一键调优产品设计计划
功能调优的典型进程包括四个环节:目标检测、瓶颈定位、功能优化、事务 SLA。这 4 个环节看起来简单完成起来并不容易。
首要,经过目标检测得到功能瓶颈便是一个很杂乱的进程:往往需求借助 10+ 检测东西,环绕 4+ 维度、100+ 目标,进行多个层面的剖析,归纳后得瓶颈定论。
其次,即便知道了瓶颈在哪里,并不意味着就能优化它:针对每一个瓶颈点,往往需求结合专家经历并重复测验,才或许找到可行的优化办法。
为了让功能调优能够被更多用户运用,所以百度智能云将这 4 步骤优进程进行了自动化,推出了 Btune ,完成了一键调优的作用。
接下来,咱们首要环绕以上几个进程打开,进一步共享 CPU 功能调优在技能上的应战,再回到 Btune 本身来介绍他的产品设计思路。
第一步:目标检测。
这儿边的首要问题是:从硬件/内核/runtime/应用数据维度许多,这些目标的相关剖析东西众多,运用办法和依靠环节杂乱。
这个层面的问题咱们看到商场上有一些功能剖析展现的产品,现已能够一定程度地处理。所以这儿不打开了。
第二步:瓶颈剖析
从东西目标到瓶颈定论仍然是一个杂乱的进程。经典的瓶颈剖析办法,咱们都知道。
-
USE:从资源运用率、饱和度、错误三个维度进行瓶颈剖析。看哪里的资源耗费多,是首要的资源瓶颈。
-
TSA:经过时刻片剖析,看哪个环节时刻耗费最长。
-
TMA:从 CPU 资源角度,去剖析程序资源 bound 在哪里。
以上三种办法指向一个核心问题,一个程序在某个方面资源耗费多、时刻耗费长、资源 bound,是合理的还是不合理的?其实,有时分是合理的,有时分是不合理的,这个跟程序行为有关。咱们要差异它、判断它,才干进一步去看能不能优化它。
这儿举一个瓶颈定位的实际生产比方。
这个比方布景是这样的,某个根据 spark 的大数据事务模块,从 x86 渠道搬迁到 ARM 渠道,发现有几个常尾延时高的节点,需求定位功能瓶颈原因。
咱们当时的定位进程是这样的:
-
首要看资源目标:CPU/MEM/网络资源运用比较低,I/O 资源无显着差异;
-
然后咱们发现网络丢包重传高,一起程序在 DFS 网络数据读取上耗费了过多的时刻。为什么会这样呢?
-
进一步调查 DFS 网络数据读写操作,发现 DFS 网络数据读写耗费了许多时刻在 skb_buffer 网络数据复制;
-
进一步看内核 skb_buffer 数据复制,发现长尾节点比非长尾节点存在更多跨路内存数据复制。为什么会这样呢?
-
进一步看程序内存分配状况和体系设置,发现长尾节点存在跨路数据复制的原因是进程内存没有绑定 NUMA,正常节点是绑定 NUMA 的。
经过以上 5 个进程,咱们才得出定论:程序地点容器没有合理绑定 NUMA,导致 skb_buffer 内存跨路复制变慢,影响网络功能。
从这个比方能够看到,要定位到瓶颈定论,往往需求多个层面的信息,归纳判断,这是一个比较杂乱的进程。
第三步:功能优化。
即便知道了瓶颈点,怎么针对瓶颈进行优化,许多状况还是无从下手。
比方说咱们剖析实际事务的时分,会得出下图这些定论,咱们知道了程序的资源瓶颈在哪里、时刻耗费在哪里、CPU 资源 bound 在哪里。但怎么优化他们,仍然是个问题。
这儿再举一个功能优化的比方。
这个比方的布景是这样的,某个广告检索的 ranker 模块,运转在 x86 渠道,希望进一步优化其功能。
咱们先后找到 3 个或许的优化点,并进行了优化和测验。
第一个,优化热门函数:
找到程序热门最高的函数 general_top 测验优化。经过函数 TMA 剖析,发现其归于分支猜测 miss Bound。进一步剖析函数代码,发现有些分支能够优化,所以进行了函数代码的优化。
在经过优化后,函数 30s 内运转耗时从 10s 削减到 7s,削减了 30%,函数优化作用非常显着。可是在经过实际测验后,程序全体功能没有大的变化,平响只下降 0.5ms。
第二个,优化内存分配:
咱们发现这个程序耗费了许多时刻在内存分配上。一起从火焰图查找能够看到内存分配栈 calloc 比 malloc 还高。
calloc 代表的是大块内存,分配功能差,常常会有 page fault。malloc 代表的是小块内存,多为红黑树和 hash 表被迫分配。所以咱们优化代码替换掉 calloc。优化后发现作用不显着,首要原因还是代码修正点在全体耗时占比不高。
第三个,优化内存分配:
咱们看到程序全体的读换页占比很高,所以测验经过使能大页的办法,削减内存换页的压力。
测验发现,使能大页后,读换页从 4.8% 下降到 1.8%。程序延时均匀下降 3ms,97 分位 10-12ms,qps 添加 28.5%。程序全体功能优化作用显着。
从这个比方能够看到,要针对某个瓶颈进行优化,往往需求结合专家经历并重复测验,才或许找到可行的优化办法。
这儿的首要问题有两个。首要,许多瓶颈点不一定能找到有效的优化办法,需求重复测验验证。其次,有时分咱们发现了一个瓶颈点,尽管针对这个瓶颈点咱们能优化它,可是假设这个瓶颈不是首要矛盾,即便针对这个瓶颈进行了优化,可是程序全体的功能并不会有太大改进。
针对上面说到的瓶颈定位和功能优化难题,百度智能云推出了如下的处理计划。
- 瓶颈定位:
咱们觉得 USE/TSA/TMA 剖析办法能够从不同层面得到功能瓶颈,但还不够直接。这些点有或许是首要矛盾,也或许不是首要矛盾。
百度智能云的计划是经过 USE/TSA/TMA 三方面信息,得到程序资源散布、耗时散布、线程联系。然后根据这些信息,利用自研的瓶颈剖析树模块,经过自顶向下的办法,从 CPU、内存、磁盘、网络、并行度 5 个维度对负载瓶颈进行全面功能剖析,得到确定性的功能瓶颈点。
- 功能优化:
每个瓶颈点该怎么优化,百度智能云现在的计划是根据团队在功能调优进程中的事例,汇总成瓶颈点和优化主张相关知识库,从而完成瓶颈定位和功能优化的闭环。
这儿打开介绍下瓶颈剖析树。
瓶颈剖析树把瓶颈定位的进程逻辑化为树的深度优先遍历进程。遍历的进程便是将负载的瓶颈定位规模逐渐缩小的进程,直到叶子结点。下图右边是一个内存部分瓶颈剖析树的简易示例图。
以事例 1 为例,首要定位到程序为内存资源瓶颈,然后发现内存读写慢,进一步发现内存 TLBMiss 偏高,进一步发现机器匿名大页未敞开。这样一步步遍历,得到瓶颈定论。
下图的事例 2 和事例 3,也是相同的自顶向下的剖析进程。
这儿打开介绍下功能优化。
瓶颈剖析树的每个叶子结点都对应了一个终究的瓶颈定论,而每个叶子结点都有相应的优化主张与之对应。每个瓶颈点所对应到的优化办法,来自于百度多年调优实践事例,这些事例终究汇聚成为了专家知识库。
下面是上文 3 个事例对应的瓶颈定论和可行优化主张。
根据上述计划,百度智能云推出了一款功能调优套件 Btune,支撑多元 CPU 加快,现在现已掩盖百度智能云的悉数核算类产品。
在 Btune 中挑选机器实例和进程后,点击一键剖析,几分钟就能够生成功能剖析报告,得到程序的瓶颈定论和优化主张。
在 Btune 供给的瓶颈定论和优化主张报告中包括两部分:剖析摘要和剖析概况。
-
剖析摘要:明晰地展现了事务功能瓶颈点和相应的优化主张,能够满意绝大部分场景的需求。
-
剖析概况:供给了更具体的功能剖析数据,从体系配置、体系功能、进程线程模型、函数指令热门等多个维度出现负载的运转特性,满意用户更细粒度功能优化。
除了功能调优套件 Btune 之外,百度智能云行将推出加快套件 BtuneAK。
-
Btune:一键功能调优助手,能够快速定位瓶颈并得到优化主张。
-
BtuneAK:打通功能优化的最终一环,一键使能,提高事务功能。
Btune 相关套件在百度智能云 BBC 和 BCC 核算实例上都是免费运用的。
3 百度智能云的调优实践
第一个比方,检索子体系需求进一步优化延时。经过 Btune 剖析得到剖析摘要。瓶颈定论为:内存子体系反常,要害瓶颈在 TLB,监测到体系没有敞开大页。优化主张为:体系层,体系敞开通明大页。使能优化主张后,均匀推迟优化 3.9%~4.6%,97 分位推迟优化 4.6%~4.7%。
第二个比方,某排序服务模块根据 BRPC 构建,CPU 利用率高。经过 Btune 剖析得到剖析摘要。CPU 子体系反常,要害瓶颈在 usr 态,steal_task 操作瓶颈,监测到 Bthread 形式为 steal_task。优化主张为:应用层,优化 Bthread 形式,用 GlobalBalancer 替换 steal_task。使能优化主张后,CPU 均匀利用率下降 25.8%。
第三个比方,某数据存储服务,许多的读写恳求超过 28ms,突破 SLA 要求。经过 Btune 剖析,得到剖析摘要。瓶颈定论:进程和读写磁盘分属不同 node 功能差,导致磁盘I/O 瓶颈。优化主张为:硬件层,磁盘亲和(进程地点 node,运用本 node 磁盘)。使能优化主张后:均匀恳求延时下降 17%,99 分位恳求延时下降 11.7%。
以上便是我今天和大家共享的悉数内容了。
———-END———-
引荐阅读