黄朝波 · 9月14日

剖析仓库级计算机:Google数据中心生产环境工作负载分析 (一)

本文是哈佛大学和谷歌等机构联合研究的一份论文,基于谷歌数据中心工作任务负载整体和细节技术原理的细致分析,并给出了数据中心性能优化的方向建议。对数据中心软硬件架构和性能优化有非常好的指导意义。

参考文献:
Profiling a warehouse-scale computer, Svilen Kanev, Juan Pablo Darago, etc., ISCA’15
作者:斯维伦·卡涅夫、胡安·巴勃罗·达拉戈、金·黑兹伍德等

0 摘要

随着仓库级计算机(WSC,Warehouse-Scale Computer)和云计算的日益流行,了解服务器应用程序与底层微架构的相互影响变得越来越重要,只有这样才能从服务器硬件中获得最大的性能。为了帮助理解,本文对运行时的数据中心作业进行了详细的微架构分析,在三年时间里在20000多台Google机器上进行了测量,包括数千个不同的应用程序。

我们首先发现,WSC工作负载极其多样化,这就催生了对,能够容忍应用程序的变化而不会损失性能的架构,的需求。然而,出现了一些模式,为硬件和软件的协同优化提供了机会。例如,我们确定软件堆栈较低层次的常见构建块。这种“数据中心税”可能占队列中运行的作业周期的近30%,这使其成为未来服务器片上系统硬件优化的主要候选。我们还发现了服务器处理器经典微架构优化的机会,特别是在缓存层次结构中。典型的工作负载对指令缓存施加了很大的压力,并且相比内存带宽,对内存延迟更加敏感。它们也经常停顿CPU内核,但在突发中计算量很大。这些观察为未来仓库规模的计算机提供了一些有趣的方向。

1 简介

最近的趋势表明计算正在向两个极端迁移:一方面是软件即服务和云计算,另一方面是功能更多的移动设备和传感器(“物联网”)。鉴于后一类通常由云中的后端计算支持,设计下一代云和数据中心平台是未来计算机架构的最重要挑战之一。

用于云计算和大型互联网服务的计算平台通常托管在大型数据中心,称为仓库级计算机 (WSC) [4]。这种仓库级计算机的设计挑战与传统服务器或托管服务的设计挑战大不相同,并且强调跨越数千个计算节点的互联网规模服务的系统设计,以实现大规模的性能和成本效益。例如,Patterson和Hennessy假设这些仓库级计算机是架构师必须设计的一类明显新的计算机系统[19]:“数据中心即计算机[41]”。

在这样的规模下,了解性能特征变得至关重要——即使性能或利用率的微小改进也可以转化为巨大的成本节约。尽管如此,对于运行时、仓库级的应用程序与底层微体系结构的相互作用的研究却令人惊讶地缺乏。虽然确实存在对孤立数据中心基准测试[14, 49],或WSC的系统级特征[5, 27]的研究,但对大规模部署的详细性能特征知之甚少。

本文介绍了第一个(据我们所知)运行时生产环境仓库级计算机的分析研究。我们在三年内对数万台服务器机器运行数十亿用户使用的工作负载和服务的纵向研究的基础上,对微架构事件进行了详细的定量分析。我们强调了计算机架构师的重要模式和见解,其中一些与传统的优化类SPEC或开源横向扩展工作负载的普遍见解截然不同。

我们的方法论解决了分析大型仓库级计算机的关键挑战,包括微架构停顿周期的细致分析和工作负载足迹的时间分析,优化以解决数据超过36个月的变化(第2节)。尽管从WSC中提取最大性能需要许多系统组件的共同而细致的协调[4],但我们选择首先关注服务器处理器(这是系统功率和性能[25]的主要决定因素),这是了解WSC性能的第一个步骤。

从软件的角度来看,我们展示了工作负载行为的显著多样性,没有单一的“银弹”应用程序来优化,也没有主要的应用程序内部热点(第3节)。虽然我们在应用程序中几乎没有发现热点行为,但在整个数据中心周期中占很大一部分的应用程序中存在通用程序。大多数这些热点都在执行超越单台机器的计算所特有的功能——我们称之为“数据中心税”的组件,例如远程过程调用、协议缓冲区序列化和压缩(第4节)。这种“税收”为微架构优化(例如,核内和核外加速器)提供了有趣的机会,可应用于未来的数据中心优化服务器片上系统(SoC)。

然而,仅仅优化税收并不足以获得根本性的绩效提升。通过深入研究内核利用率低的原因(第5节),我们发现缓存和内存系统是优化服务器处理器的重要机会。我们的结果表明,指令缓存瓶颈是一个重要且日益严重的问题。前端核心停顿占所有流水线槽的15-30%,许多工作负载显示5-10%的周期完全缺乏指令(第6节)。许多关键工作负载的指令足迹显示出显著的增长率(每年30%),大大超过了当前指令缓存的增长,尤其是在缓存层次结构的中间级别。

也许不出所料,数据缓存未命中是停顿周期的最大部分,占50%到60%(第7节)。与内存带宽相比,延迟是一个明显更大的瓶颈,我们发现它为我们的工作负载过度配置。典型的数据中心应用程序组合涉及访问模式,这些模式表示计算突发与停顿时间突发混合在一起,这对传统设计提出了挑战。这表明虽然宽的、乱序的内核是必要的,但它们的使用效率通常很低。虽然同时多线程 (SMT) 有助于隐藏延迟和重叠停顿时间(第8节),但依赖当前的2路SMT不足以消除我们观察到的大量开销。

总体而言,我们的研究为未来的微架构探索提出了几个有趣的方向

  • 设计更多具有附加线程的通用内核以解决广泛的工作负载多样性;
  • 为“数据中心税”组件提供特定的加速器;
  • 改进对内存层次结构的重视,包括优化权衡延迟的带宽,以及更加强调指令缓存优化(分区I-Cache/D-Cache 等)。

在寻求性能更高的仓库级计算机时,这些领域中的每一个都值得进一步研究。

2 背景和方法

这项研究对大型生产环境仓库级计算机进行了概要分析,汇总了数千个应用程序的性能数据,并确定了这种规模的架构瓶颈。本节的其余部分描述了典型的WSC软件环境,然后详细介绍了支持此类分析的方法。

背景:WSC 软件部署 我们首先简要描述现代仓库级计算机的软件环境,作为了解处理器在数据中心软件堆栈下的执行方式的先决条件。虽然下面描述的习语是基于我们在Google的经验,但它们是大型分布式系统的典型代表,并且普遍存在于其他平台即服务云中。

数据中心孕育了分布式、多层服务的软件架构,其中每个单独的服务公开一组相对狭窄的 API。服务之间的通信仅通过远程过程调用(RPC)[17]。请求和响应以通用格式序列化(在Google,协议缓冲区[18])。延迟,特别是在整个分布的尾端,是定义性能的指标,并且有大量技术用来减少延迟[11]。

具有窄API的小型服务的主要好处之一是相对易于测试和部署。这鼓励了快速的发布周期——事实上,谷歌内部的许多团队每周甚至每天发布一次。几乎所有Google的数据中心软件都存储在一个共享存储库中,并由一个构建系统构建[16]。因此,代码共享很频繁,二进制文件大多是静态链接的,以避免动态依赖问题。通过这些传递依赖,二进制文件的大小通常达到100 MB。因此,数据中心CPU面临着多种多样的工作负载,具有大量指令占用空间和共享的低层级例程。

持续分析 我们使用Google-Wide-Profiling(GWP)[44]从许多实时数据中心工作负载中收集与性能相关的数据。GWP基于数据中心内的机器和机器内的执行时间的低开销随机抽样的前提。它的灵感来自DCPI等系统[2]。

简而言之,GWP收集器:

  • 随机选择一小部分谷歌服务器群来每天进行分析;
  • 在每台被测机器上在短时间内远程触发配置文件收集(通常通过perf [10]);
  • 对收集到的样本的调用堆栈进行符号化(以便它们被标记为相应的代码位置)
  • 将来自许多机器的大量此类样本聚合到Dremel数据库[37]中以便于分析。

Ren等人[44]详细描述了GWP收集流水线。

几年来,GWP一直在悄悄地对Google的数据中心集群进行抽样,这使其成为纵向研究的完美工具,这些研究可以解释在很长一段时间内成本花费在了哪里。我们在以下部分进行了多项此类研究,持续时间为12-36个月。

我们将这些研究集中在用C++编写的代码上,因为它是消耗CPU周期的主要语言。就人气而言,情况不一定如此。大量代码(以代码行数衡量)是用其他语言(主要是Java、Python和Go)编写的,但是这些代码只占整体周期的一小部分。专注于C++还简化了对每个收集样本的调用堆栈的符号化。这些符号化调用堆栈的聚合集支持超越应用程序边界的分析,并允许我们以真正的仓库规模搜索热点。

特定于体系结构的集合 为了分析仓库级应用程序与底层硬件之间更微妙的关系,我们使用处理器性能计数器,而不仅仅是将周期归因于代码区域。我们重用GWP的大部分基础架构来收集性能计数器并询问特定于微架构的问题。由于计数器与特定的微架构有着错综复杂的联系,因此我们将此类研究限制在配备Intel Ivy Bridge处理器的机器上。

更详细地说,对于每个这样的专用集合,我们随机选择20000台Ivy Bridge机器,并分析在它们上运行的所有作业,以收集相应性能计数器的1秒样本。对于每线程测量,我们还收集了适当的元数据,以将样本归因于执行线程的特定作业及其各自的二进制文件(通过perf的容器组支持)。我们还特别注意验证我们与微基准测试一起使用的性能计数器(更奇特的性能计数器中的勘误表可能很常见),并且仅使用可以在单个测量中满足核心性能监控单元 (PMU)约束的计数器表达式(时分复用PMU通常会导致错误的计数器表达式)。最后一个要求限制了我们执行的分析。评估不适合单个PMU的复杂计数器表达式的常见做法是,在同一应用程序的多次运行期间简单地收集必要的计数器。在采样场景中,这并非普遍适用,因为计数器表达式的不同部分可能来自不同的样本,并且需要特殊的标准化才能相互比较。

我们在单PMU块中收集的所有表达式都是比率(由循环或指令标准化)并且不需要这种特殊处理。它们的单个样本可以相互比较并聚合,无需任何额外的归一化。我们通常显示这些样本的分布,压缩在箱线图中。围绕中值绘制的方框代表此类分布的第25个和第75个百分位数,而曲线(在所示图中)代表第 10 个和第 90 个百分位数。

WeChat Image_20210914113734.jpg

表1:任务描述

WeChat Image_20210914113748.jpg

图1:没有要优化的“杀手级应用”。

前50个最热门的二进制文件仅覆盖了约60%的WSC周期。

性能计数器分析 我们使用一种性能分析方法,称为自上而下,最近由Yasin提出[48]。自顶向下允许在现代乱序处理器中重建近似的CPI堆栈,如果没有专门的硬件支持,这项任务被认为是困难的[13]。我们使用的确切性能计数器表达式与自顶向下工作中列出的表达式相同[48]。

与其他周期计数方法类似[6, 13],自顶向下计算每个周期微架构停顿事件的成本,而不是其他传统的指标(例如未命中率、每千条指令未命中率–MPKI),量化此类活动中的最终成本表现。这对于具有广泛延迟隐藏机制的现代复杂乱序处理器尤其重要。例如,L1指令缓存中MPKI的较高的数值可能会引发错误警报以优化指令占用空间。事实上,现代CPU内核的前端有足够的缓冲,仅在L1中的未命中对终端性能的影响很小。

工作负载 虽然我们确实观察到工作负载越来越多样化,但我们专注于12个二进制文件(表 1)进行深入的微架构分析。主要的选择标准是多样性。因此,我们最终得到了来自多个广泛应用程序类别的作业——批处理(视频、索引)与延迟敏感(其余);低级服务(磁盘、bigtable)通过后端(gmail、搜索)到前端服务器(gmail-fe)。我们努力包含各种微架构行为——不同程度的数据缓存压力、前端瓶颈、提取的IPC等。我们还报告了比精选的12种二进制文件数量多得多的平均值。

最后,我们做出了一个简化的假设,即一个应用程序等于一个二进制文件,并可以互换使用这两个术语(Kambadur等人[24]描述了数据中心设置中的应用程序描述权衡)。这对上述12个工作负载的任何结果没有影响,因为它们由单个二进制文件组成。

3 工作负载多样性‌

WeChat Image_20210914113752.jpg

图 2:工作负载越来越多样化。在前50个最热的二进制文件中花费的周期比例正在减少。

这项研究最明显的结果是现代仓库级计算机中工作负载的多样性。虽然WSC最初创建时考虑的是“杀手级应用程序”[5],但“数据中心即计算机”的模型已经发展壮大,当前的数据中心处理快速增长的应用程序池。

为了证实这一点,我们对在谷歌仓库级计算机上运行的应用程序进行了 3 年多的纵向研究。图1显示了研究的最后一周应用程序之间 CPU 周期的累积分布。很明显,没有一个应用程序在分布中占主导地位——最热的应用程序占了10%的周期。此外,需要50个不同的应用程序来占用多达60%的周期。

图1只是持续多元化趋势的一个片段。我们在图2中证明了这一点,该图绘制了每周研究的50个最热二进制文件中花费的CPU周期的分数。虽然在我们检查的最早时期,50个应用程序足以占执行时间的80%,但三年后,相同的数量(不一定是相同的二进制文件)覆盖了不到60%的周期。平均而言,前50名二进制文件的覆盖率在3年多的时间里以每年5个百分点的速度下降。请注意,该数据集不包括与公共云相关的数据,这使程序员可以访问仓库规模资源的数量增加了几个数量级,从而进一步增加了应用程序的多样性。

应用程序也表现出多样性,它们本身具有非常平坦的执行配置文件。我们用来自search3的CPU配置文件来说明这一点,该配置文件在该特定应用程序的典型大小的集群上执行了一周的时间汇总。图3显示了CPU周期在叶子函数上的分布——最热的单个函数只负责6.3%的周期,而它需要353个函数来占80%的周期。这种尾部沉重的行为与之前的观察结果形成鲜明对比。例如,另一个横向扩展工作负载,来自CloudSuite的数据分析已被证明包含重要的热点——3个函数负责65%的执行时间[49]。

WeChat Image_20210914113757.jpg

图 3:单个二进制文件已经经过优化。没有热点的示例二进制文件,并且具有非常平坦的执行配置文件。

从软件工程师的角度来看,在应用程序和功能级别上都没有明显的热点,这意味着数据中心范围的分析是无可替代的。虽然在每个应用程序的基础上优化热点是有价值的,但与优化平面轮廓相关的工程成本并不总是合理的。这促使谷歌越来越多地投资于自动化、编译器驱动的反馈导向优化。然而,针对跨应用程序的正确通用构建块可能会对整个数据中心产生更大的影响。

从架构师的角度来看,同样不太可能为如此大量的代码找到一个瓶颈。相反,在本文的其余部分,在汇总了运行这些工作负载的数千台机器之后,我们指出了几个较小规模的瓶颈。然后我们将它们与设计未来WSC服务器系统的建议联系起来。

4 数据中心税‌

尽管第3节显示了显著的工作负载多样性,但一旦我们在数据中心中运行的许多应用程序中聚合采样的配置文件数据,我们就会看到共同的构建块。在本节中,我们量化了数据中心税对性能的影响,并认为其组件是未来数据中心SoC中硬件加速的主要候选者。

我们确定了该税收的六个组成部分,详述如下,并估计它们对我们WSC中所有周期的贡献。图4显示了这一特征在11个月内的结果——“税收周期”始终占所有执行的22-27%。在应用程序数量不断增加的世界中(图2),优化此类应用程序间通用构建块可以显着提高性能,这比在单个二进制文件中寻找热点更重要。我们观察到几乎所有时间都在纳税的服务,并且会从减少税收中获得不成比例的收益。

我们包含在税收分类中的组件是:协议缓冲区管理、远程过程调用(RPC)、散列、压缩、内存分配和数据移动。为了在它们之间清楚地归属样本,我们仅使用leaf执行配置文件(基于程序计数器的分箱,而不是完整的调用堆栈)。对于leaf配置文件,如果样本出现在代表RPC调用的malloc()中,则该样本将归因于内存分配,而不是RPC。这也保证了我们总是低估在税法中花费的周期比例。

虽然税收的某些部分更特定于WSC(protobuf和RPC),但其余部分足够通用,可用于各种计算。在选择将哪些跨应用程序构建块归类为税收时,我们选择了通常成熟的低等级例程,它们也相对较小且独立。这种小的、缓慢变化的、广泛使用的例程非常适合硬件优化。在以下段落中,我们勾勒出加速每个税收组成部分的可能方向。

WeChat Image_20210914113800.jpg

图4:22-27%的WSC周期用于“数据中心税”的不同组成部分。

Protobuf管理 协议缓冲区[18]是谷歌内部数据存储和传输的通用语言。针对WSC的代码中最常见的习惯用法之一是将数据序列化到协议缓冲区,在将序列化的协议缓冲区传递给远程被调用方的同时执行远程过程调用,并返回需要反序列化的类似序列化响应。这种流中的序列化/反序列化代码由protobuf编译器自动生成,因此程序员可以使用他们选择的语言与本机类进行交互。生成的代码是图4中protobuf部分的大部分。

协议缓冲区的广泛使用,部分是由于编码格式随时间的稳定性。它的成熟还意味着在服务器SoC中构建用于protobuf(反)序列化的专用硬件可以成功,类似于XML解析加速器[9, 46]。像其他数据密集型加速器[28]一样,这种专用的protobuf硬件可能应该驻留在更靠近内存和最后一级缓存的地方,并从靠近内存的计算中获得好处。

远程过程调用(RPC) RPC在WSC中无处不在。RPC库执行多种功能,例如负载平衡、加密和故障检测。在我们的税收细分中,这些共同承担了大约三分之一的RPC税收周期。其余的由有效载荷的简单数据移动占用。已经提出了通用数据移动加速器[12]并且对后一部分有帮助。

数据移动 事实上,RPC 并不是唯一进行数据移动的代码部分。我们还跟踪了对memcpy()和memmove()库函数的所有调用,以估计显式数据移动(即通过简单API公开)所花费的时间。这是一个保守的估计,因为它不跟踪内联或显式副本。仅这两个库函数的变体就代表了4-5%的数据中心周期。最近的工作,在DRAM中执行数据移动[45],可以优化掉这部分税。

压缩 大约四分之一的税收周期用于压缩和解压缩数据(仅在此类别中包括通用无损压缩,而不包括音频/视频编码)。压缩分布在几种不同的算法中,每种算法强调压缩比/速度谱中的不同点。潜在的硬件加速压缩不一定是这种情况。例如,snappy算法专门设计用于实现比gzip更高的(解)压缩速度,从而在过程中牺牲压缩率。如果存在足够快的硬件以进行更好的压缩算法,它的使用可能会减少[30, 39]。

内存分配 内存分配和解除分配构成了WSC计算的重要组成部分(如图4中的分配所示),尽管在软件中对其进行了大量优化[15, 29]。当前的软件实现大多基于递归数据结构,并与操作系统交互,这使得它们在硬件中实现并不容易。然而,潜在的好处表明在这个方向上的调查是值得的。

哈希 我们还在税收周期的定义中包含了几种哈希算法,以估算密码加速器的潜力。哈希代表服务器周期的一小部分,但一致的部分。由于使用的哈希值种类繁多,这是一个保守的估计。

CPU内核 作为共享工作负载组件的内核值得额外提及。它显然无处不在,而且WSC应用程序几乎五分之一的CPU周期都花在内核中也就不足为奇了(图5)。但是,我们不认为它是加速征税——它既不小,也不自成一体,当然也不容易用硬件替换。这并不是说在软件中进一步优化它没有好处。作为一个例子,考虑图5中的调度程序,它必须处理许多不同的应用程序,每个应用程序都有更多的并发线程(90%的机器同时运行大约4500个线程[50])。即使经过大量调整[47],仅调度程序就占所有数据中心周期的5%以上。

WeChat Image_20210914113804.jpg

图 5:内核时间,尤其是在调度程序中花费的时间,是WSC周期的重要组成部分。

5 微架构分析‌

WeChat Image_20210914113806.jpg

图6:顶层的瓶颈分解。SPEC CPU2006 基准测试没有表现出WSC基准的低隐退率和高前端有界性的组合。

类似于“数据中心税”的较小组件,它们共同构成了所有周期的很大一部分,我们预计在微架构级别上会出现多个性能瓶颈。为了轻松识别它们,我们使用自上而下[48]性能分析方法,我们将其纳入我们的集群测量基础设施中。

自顶向下选择现代乱序处理器的微操作 (µop) 队列作为内核前端和后端之间的分界点,并用它来分类µop流水线插槽(即潜在提交的µop)分为四大类:退出、前端边界、错误推测、后端边界。其中,只有Retiring 被归类为“有用的工作”——其余的都是开销来源,阻止工作负载利用整个内核宽度。

由于这种单点划分,这种开销的不同组成部分是相加的,非常类似于传统CPI堆栈的组成部分。详细的方法递归地将每个开销类别分解为更具体的子类别(例如,后端绑定到核心绑定、L1绑定等),从而朝着越来越具体的微架构瓶颈的方向推动分析。我们主要关注顶层细分及其几个直接子项——更深的子类别需要更复杂的计数器表达式,在采样执行中更难准确收集,如第2节所述。

四个顶层类别的细分可以用一个简单的决策树进行总结。如果一个µop离开了µop队列,它的槽可以被归类为退出或错误推测,这取决于它是否进入提交阶段。类似地,如果一个 µop队列槽在一个特定的周期内没有变空,可能有两个原因:它开始时是空的(前端绑定),或者后端没有为另一个µop做好准备(后端绑定)。这些可以简单地通过后端停顿信号来区分。直观地说,前端边界捕获与获取、指令缓存、解码和一些较小代价的前端重新控制相关的所有开销,而后端边界由数据缓存层次结构和缺乏指令级并行而引起的开销组成。

我们将此方法应用于图6中数据中心工作负载的开销。它包括几个具有众所周知行为的 SPEC CPU2006基准测试作为参考点:

  • 400.perlbench – 高 IPC,最大的I-Cache工作集;
  • 445.gobmk - 难以预测的分支,最高IL1 MPKI;
  • 429.mcf, 471.omnetpp – 受内存限制,强调内存延迟;
  • 433.milc – 受内存限制,强调内存带宽。

图 6 中的第一个直接观察结果是退出µops的一小部分——与SPEC (429.mcf)中看到的最低值相似或通常更低。这意味着大多数数据中心工作负载将内核的时间花费在各种瓶颈上。大多数这些停顿槽显然是由于后端压力造成的——除了search2和search3超过60%的µop槽由于后端而被阻塞。我们将在第7节中更仔细地研究这些。错误的推测插槽在SPEC套件定义的范围内。更仔细地检查,12个WSC应用程序显示分支错误预测率在445.gobmk和473.astar的0.5到2之间,其余的SPEC低于该区间的下限。

最后,与SPEC基准相比,一种明显突出的行为是前端压力导致的大部分停顿。我们将在下一节中研究它们。

END

作者:Svilen Kanev etc
来源:https://mp.weixin.qq.com/s/W3FOWorzGqehV9Aep7os\_A
微信公众号:
软硬件.jpg

相关文章推荐

更多软硬件技术干货请关注软硬件融合专栏。
2 阅读 150
推荐阅读
0 条评论
关注数
1268
内容数
41
软硬件融合
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
Arm中国学堂公众号
关注Arm中国学堂
实时获取免费 Arm 教学资源信息
Arm中国招聘公众号
关注Arm中国招聘
实时获取 Arm 中国职位信息