DynSleep:面向延迟敏感型数据中心应用的细粒度功耗管理
摘要
数摘据要中心中运行的服务器通常处于低利用率状态,以满足严格的延迟目标。由于商用服务器的能耗比例性较差,这种低利用率导致了浪费性的功耗,每年造成数百万美元的开销。
在数据中心工作负载上应用动态电源管理具有挑战性,尤其是当尾部延迟要求常常处于亚毫秒级时。根本问题在于请求到达时间和请求服务时间的不可预测性所带来的随机性。以往的技术采用单核DVFS,通过细粒度控制减缓请求处理速度,从而不违反尾部延迟目标。然而,大多数商用服务器仅支持单核DFS,这极大地限制了节能潜力。本文提出DynSleep,一种利用单核睡眠状态(C状态)实现细粒度电源管理的数据中心工作负载管理方案。DynSleep动态推迟部分请求的处理,制造更长的空闲时段,从而能够使用更深的C状态以节省能耗。
我们基于Memcached——一种在数据中心广泛使用的键值存储应用——设计并实现了DynSleep。实验结果表明,DynSleep最多可实现核心功耗降低65%,比单核DVFS电源管理方案节能高出27%,同时仍能满足尾部延迟约束。据我们所知,这是首个针对延迟敏感型数据中心工作负载,分析并开发基于中央处理器C状态的电源管理技术的工作。
CCS概念
• 硬件 ➝ 芯片级功耗问题
• 硬件 ➝ 企业级和数据中心功耗问题
关键词
电源管理、尾部延迟、数据中心工作负载、睡眠状态、Memcached应用和服务质量
引言
延迟敏感型应用在当前数据中心中十分常见,给系统设计人员带来了新的挑战。对于这些应用程序而言,决定服务质量的是尾部延迟,而非平均延迟。运行延迟敏感型工作负载的服务器通常保持较低的负载为了满足这些延迟目标而加载,典型的利用率为5%到25% [1,3]。这种低利用率每年造成数十亿美元的浪费,因为服务器不具备按能耗比例运行的特性,并且在服务器利用率较低的时期能效较差 [1,6,12,14]。
这些数据中心工作负载通常可被视为请求/响应模型,并表现出一种开/关执行模式[7]。在忙时周期(也称为busy period)期间,即请求正在被处理时,CPU核心消耗有功功率。在没有请求到达的空闲周期期间,CPU消耗空闲功耗,虽然低于有功功率,但仍相当可观。现代CPU提供了一系列睡眠状态(也称为C状态),以在空闲时段实现节能。这些睡眠状态通过断电核心及其对应缓存的不同部分,以睡眠/唤醒延迟换取节能效果。因此,空闲功耗取决于核心所进入的C状态。在请求处理批次之间的空闲周期为实施电源管理提供了机会。需要注意的是,开/关周期的长度并非确定性的,而是取决于请求到达率和服务率。
尽管服务器通常保持在低负载状态下运行,但在设定适当的目标尾部延迟时,通常会考虑峰值负载。考虑到这一事实,显然可以看出,在低负载下运行的服务器其尾部延迟将远低于目标值。图1展示了在轻负载下运行的服务器延迟的累积分布函数。我们可以看到,该服务器的尾部延迟(绿色虚线)与目标尾部延迟(红色虚线)之间存在“延迟余量”。这种延迟余量为实现能耗比例性提供了机会。已有若干技术 [6,14,15]提出通过应用动态电压频率调节(DVFS)来利用这一延迟余量。然而,这些技术对延迟敏感的数据中心工作负载所带来的节能效果有限。DVFS只能降低动态功耗,而静态功耗在当今的多核处理器中已占据主导地位[10]。此外,随着芯片制造工艺的进步,频率调节的空间不断缩小,限制了利用延迟余量实现节能的机会[8]。许多先前的技术假设具备细粒度的每核电压和频率可用的控制在数据中心部署的大多数服务器中并不存在。大多数商用服务器仅具有每核频率控制和芯片级电压控制[9]。
其他先前的工作 [3,4,13]通过利用CPU睡眠状态来节省功耗。
PowerNap [3]在CPU空闲时将其置入深度睡眠状态,并在请求到达时唤醒。尽管该方法在服务时间较长的应用程序上表现出良好的节能效果,但由于较高的睡眠状态转换开销以及短空闲期,使得该技术对于Memcached等应用程序而言并不具备良好的节能效率。文献[4]中提出了Vacation方案,通过延迟请求处理以创造空闲时段,从而高效利用深度睡眠状态。然而,该技术在此场景下并不适用,因为其使用统计排队模型在较长时间段内确定延迟时间。数据中心的流量具有高度短期波动性,请求到达通常呈现突发性。这些短期流量峰值通常主导尾部延迟[5,6],而无法被统计模型准确捕捉。文献[13]中提出了Dream-Weaver,通过任务延迟和抢占来对齐各核心的空闲时段,从而将整个多核处理器置入深度睡眠状态。然而,由于缺乏细粒度的每核心控制,多个核心之间的流量变化性将极大地削弱进入处理器级睡眠状态的机会。
为了解决这些问题,我们提出了DynSleep,一种通过动态推迟请求处理并利用深度睡眠状态来节省功耗的细粒度电源管理方案。现有技术[3]与我们的技术之间的主要区别在于,当请求到达时,并非立即唤醒核心,而是在睡眠期间对请求进行排队并推迟其处理。与[4,13]相比,我们的技术通过每核控制保持了现有的尾部延迟目标。在DynSleep中,睡眠周期会不断调整,以避免违反尾部延迟约束。具体而言,DynSleep的主要洞察是,睡眠状态可以有效机制地将请求延迟分布向目标尾部延迟移动。使用睡眠状态的一个主要挑战是传入流量的高度变化性,如果未加以考虑,可能会导致显著的性能影响。我们的方案通过新颖的性能建模应对流量变化性,该模型包括请求到达时间、请求处理时间的统计信息以及队列长度。该模型使得DynSleep能够在满足目标尾部延迟的同时,动态调整处于睡眠状态的CPU核心的唤醒时间。
人们普遍认为,由于数据中心严格的亚毫秒级目标尾部延迟要求,只有DVFS技术能够通过调整请求延迟分布来消除延迟余量。但我们的工作首次表明,睡眠状态也可用于消除延迟余量。
此外,我们必须指出,目前关于数据中心节能的大多数结果都是通过应用数据中心跟踪数据,并在多核服务器或模拟器上回放这些数据获得的,而不是运行真实应用[3,13,15]。在本文中,我们修改了Memcached,一种在数据中心中广泛使用的键值存储应用,并获得了实际测量结果。
总之,我们做出了以下贡献:
- 我们首先通过详细讨论现有的硬件和应用程序,探索节能与睡眠状态(C状态)之间的关系。在此我们还识别了潜在的功耗浪费来源。
- 我们提出了我们的电源管理方案DynSleep,这是一种新颖的细粒度每核心电源管理方案,通过调整每个核心的空闲时段和C状态来实现节能。
- 我们建立了一个简单的分析模型,以在每次数据包到达时重新计算睡眠时间。我们在运行时应用该模型,并通过实验验证了节能效果。
- 我们设计并实现了DynSleep,将其与数据中心中部署的流行的高性能、延迟关键型键值存储应用Memcached结合。我们在Linux的真实系统上评估了所提出的方案,并证明了其有效性。
2. 背景
2.1 CPU睡眠状态
当没有工作可做且正在等待可用任务时,CPU核心会进入空闲状态。为了避免在此等待期间产生不必要的功耗,现代CPU提供了一系列睡眠状态(也称为C状态),以便在CPU空闲时节省功耗。在我们的实验服务器中,存在三种CPU空闲功耗状态,每种状态都会禁用CPU核心中的不同组件。通过分别启用每个空闲状态,我们测量了CPU空闲状态的功耗。
我们实验服务器的C状态特性[7]如表I所示。我们还通过在服务器上进行大量实验收集了每个C状态的功耗,如表I最后一列所示。该表显示,CPU核心在更深的C状态下的功耗显著降低。我们还可以看到,进入C状态的转换开销随着C状态变深而增加,因为禁用/启用相应组件需要更多时间。在状态转换期间,核心消耗满额功耗。因此,只有当空闲持续时间大于某个阈值时,CPU核心才应进入特定的C状态,该阈值称为目标驻留时间,且随着C状态变深而增加(如表I所示)。
表I. CPU核心C状态。
| 状态 | 状态转换时间 | 目标驻留时间 | 功耗 |
|---|---|---|---|
| C0 | N/A | N/A | (3~3.5W) |
| C1 | 1μs | 1 μs | 1.2W |
| C3 | 59 μs | 156 μs | 0.13瓦 |
| C6 | 89 μs | 300 μs | 0W |
2.2 基线系统行为
在默认系统中,只要有请求在队列中,中央处理器核心就会忙于处理请求;当队列中的所有请求都处理完毕后,核心进入空闲状态。一旦有请求到达,处于睡眠状态的核心将立即被唤醒。当流量负载较低时,核心大部分时间处于空闲状态,但由于请求频繁到达导致空闲时段较短,无法满足深度睡眠状态的驻留时间要求,因此难以进入深度睡眠状态。图2a显示了Memcached应用中CPU核心在不同睡眠状态(C状态)下所花费的空闲时间比例的实验结果。在此实验中,我们运行单线程Memcached [2],并通过访问Linux中的
/sys/devices/system/cpu/cpuX/cpuidle/stateY/time
来记录在不同C状态下的停留时间。单线程Memcached的平均请求服务时间为10微秒,请求到达过程为泊松分布,速率分别为如图2a的x轴所示。
首先,随着请求到达率的增加,CPU核心处于活动状态(C0状态)的时间比例也随之增加。此外,我们可以看到,即使在低负载(10000 RPS,负载为峰值负载的 ≈ 10%)下,核心在空闲时间中也有超过75%的时间处于最浅层的睡眠状态(C1)。随着负载增加,核心在深度睡眠状态(C3和C6)中花费的时间减少,而在浅层睡眠状态(C1)中花费的时间增加。需要注意的是,在超过40000请求每秒(负载≈ 0.4)后,深度睡眠状态(C3和C6)几乎不存在,因为空闲时段太短,不足以进入深度睡眠状态。图2b给出了默认memcached在不同负载下的平均功耗分解情况,该功耗已归一化为峰值功耗。作为对比,我们还展示了能量正比(EP)核心的中央处理器核心功耗,其中功耗与利用率[11,12]成正比。能量正比可被视为“最优”的功耗表现。可以看出,默认memcached距离能耗比例性还有较大差距。在低负载时,尽管大部分时间处于C1状态,核心的空闲时段功耗仍主导了平均功耗。需注意的是,CPU核心在功耗较低的C3和C6状态中停留的时间很少。因此,C3状态对平均功耗的贡献微乎其微;C6状态不消耗功率,因此未在图2b中显示。随着负载增加,由于空闲时间减少,空闲时段功耗随之下降,但仍相当显著。尽管可能存在缓存或主存低效率等多种原因,但我们认为空闲时段对睡眠状态的低效利用是造成这种较差能耗比例性的主要原因。
CPU睡眠状态和(b)归一化平均功耗的表征)
3. 动态睡眠
3.1 动态睡眠概述
为了利用空闲时段的节能机会,我们提出了一种动态睡眠方案。
可以注意到,在请求到达时保持持续警觉并不会带来任何好处,反而会增加空闲时段的功耗,因为我们只需要满足目标尾部延迟即可。我们的思路是,CPU核心可以“拖延”并在请求到达后延迟唤醒,而不是像[3]中那样立即唤醒,只要仍能满足目标尾部延迟即可。通过这种方式,CPU核心在两个活跃时段之间的空闲时段将被延长,从而能够高效地进入深度睡眠状态以实现节能。基于这一原则,我们设计了动态睡眠方案,该方案重塑了请求处理模式,并强制创建更长的空闲时段以实现节能。
设计动态睡眠方案的挑战在于确定何时唤醒CPU核心,以确保请求的目标尾部延迟不被违反。一些先前的研究[4,13]提出了通过延迟请求处理来权衡请求延迟与节能的方法,然而这些方法在此并不适用,因为它们未考虑流量变化性。
在数据中心中,必须确保目标尾部延迟在任何时间都不被违反。数据中心的流量表现出请求延迟的短期波动性,这通常主导了尾部延迟[5,6]。我们通过在中央处理器睡眠时的请求到达时刻动态调整唤醒时间来解决此问题,从而确保每个请求都满足目标尾部延迟。
图3给出了在我们的方案中如何确定和调整CPU核心唤醒时间的具体示例。在数据中心中,目标尾部延迟以百分位数形式指定。在此示例中,我们使用95百分位数延迟目标LC,这意味着95%的请求必须在延迟L ≤ LC内得到服务。假设CPU核心在t=0时刻完成上一批请求的处理并进入睡眠状态,如图3a所示。随着时间推移,请求R1在t=A1(M)时刻到达,如图3b所示。CPU核心在t=W1(N)时刻被唤醒,请求处理时间为S1,从而满足R1的尾部延迟要求。图3c显示了当请求R2在t=A2(O)时刻到达时,R1仍在等待执行的情况。此时核心的唤醒时间被调整为W2,以确保R2的延迟不被违反(P)。类似地,当R3到达时,唤醒时间进一步调整为W3。在任何请求到达时,如果修订后的等待时间短于睡眠状态的转换时间,则核心必须立即唤醒。
在图3中,时间A3和W3之间没有请求到达,因此CPU核心将在W3时刻唤醒,并以先进先出的方式逐个处理排队请求。然而,如果在R3之后有新的请求到达,则重复上述步骤,直到满足唤醒时间。另一方面,当CPU核心处于唤醒状态时,在处理过程中到达的请求将被排入队列,这些请求将根据先进先出的队列原则进行处理。当队列变为空时,CPU核心将进入睡眠状态,随后重复上述相同的过程。需要注意的是,我们在上述方程中使用95延迟目标仅用于说明目的,该延迟目标可替换为任意延迟目标,而无需改变算法本身。此外,我们提出的方案支持每核控制,在图3中我们仅以单个核心为例进行说明。在多核处理器中,每个核心均独立遵循上述相同的原则。
-(d) 表示随着时间推移的不同时间实例。)
3.2 唤醒时间推导
设S1是一个具有概率分布PS1的随机变量,请求R1的延迟L1可以表示为:
$$ L_1 = W_1 + S_1 - A_1 $$ (1)
根据目标尾部延迟 LC,我们可以得到 W1 为 (N):
$$ L_C \geq W_1 - A_1 + S_1^{95} $$
即
$$ W_1 \leq L_C + A_1 - S_1^{95} $$ (2)
其中 X^95 表示随机变量 X 在 95% 的时间内小于 X^95。
遵循与公式(1)和(2)相同的原则:
$$ L_2 = W_2 + S_1 + S_2 - A_2 $$ (3)
$$ L_C \geq W_2 - A_2 + \hat{S}_2^{95} $$
即
$$ W_2 \leq L_C + A_2 - \hat{S}_2^{95} $$ (4)
其中 Ŝ2 = S1 + S2 是一个随机变量,其概率密度函数为 PŜ2 = PS1 ∗ PS2 (∗ 是卷积)。我们将在本节后面讨论如何计算 PŜi。与公式(2)相比,可以看出R2的延迟包含了S1,即R1的服务时间,该时间被视为R2的排队延迟。此外,唤醒时间W1是在R1到达时预先确定的,表示核心在不违反目标延迟的前提下最晚的唤醒时间,我们需要比较W2和W1之间的较早时间,并更新唤醒时间(P):
$$ W_2 = \min(W_1, W_2’) $$ (5)
通过更新新的唤醒时间,请求 R1 的尾部延迟可能会发生变化。新的唤醒时间(W2)将始终小于或等于之前的唤醒时间(W1)。因此,R1 的新 95 延迟将小于目标尾部延迟。
类似地,当R3到达A3时(图3d),W3可以通过以下方式确定:
$$ L_3 = W_3 + \hat{S}_3 - A_3 $$
$$ L_C \geq W_3 - A_3 + \hat{S}_3^{95} $$
即
$$ W_3 \leq L_C + A_3 - \hat{S}_3^{95} $$ (6)
其中 Ŝ3 = S1 + S2 + S3 和 PS3̂ = PS1 ∗ PS2 ∗ PS3
接下来,我们通过假设每个请求的服务时间独立地从一个单一的分布PS中抽取来计算概率分布,其中S表示处理一个请求所需的服务时间。由于内存系统[1]中缺乏时间局部性,该假设在数据中心节点中是成立的。因此,PS2̂ = PS ∗ PS 和 PS3̂ = PS ∗ PS ∗ PS。一般而言,
$$ \hat{S}
i = \sum
{j=1}^{i} S_j, \quad P_{\hat{S}_i} = P_S * P_S * \cdots * P_S \text{ (i times)} $$ (7)
请求的服务时间分布保持不变;可以通过离线分析或短暂的学习阶段轻松获取。给定 PS,可以预先计算 PSî 以供将来参考。
3.3 功耗行为
前两节描述了我们动态睡眠方案的详细信息。在本节中,我们将通过该方案给出一个功耗改善的示例。考虑图3所示的三次请求到达情况。在基线方案中,将产生三个空闲时段,其长度分别为:A1, A2-A1-S1, 和 A3-A2-S2。通过应用我们的动态睡眠方案,我们将获得一个更长且连续的空闲时段,从t=0到t=W3。结果,CPU核心可以进入深度睡眠状态更长时间,而不是在三个较短且不连续的空闲时段内进入浅层睡眠状态。
图4给出了基线与我们的动态睡眠方案在单个设备功耗行为上的比较。在此图中,虚线表示基线功耗,实线表示采用动态睡眠方案时的功耗。请求到达模式与图3相同。在基线情况下,核心在请求到达时被唤醒,在请求处理期间消耗有功功率,处理完成后进入空闲状态。由于空闲时段较短,核心只能进入浅层睡眠状态,因而消耗较高的空闲功耗。在动态睡眠方案中,由于请求会被暂存直至唤醒时间,核心将进入深度睡眠状态,直到被唤醒为止。同样地,核心在请求处理期间会消耗有功功率。
比较这两种方案可以看出,动态睡眠方案将请求处理模式转变为更长的空闲和繁忙周期。这大大降低了空闲时段的功耗,且对繁忙周期的功耗没有不良影响。
4. 应用实现
我们设计并实现了所提出的动态睡眠方案,并将其应用于数据中心中广泛部署的高性能键值存储应用Memcached,同时在真实系统上评估了该方案的功耗和延迟。实验设置、结果及分析将在下一节中给出。
我们使用Memcached v1.4.15[2]作为基线。图5记录了从Memcached服务器角度处理数据请求时的流程。从上到下查看图5,客户端负责向Memcached提交操作请求。当Memcached启动时,会创建固定数量的工作线程来处理这些客户端请求,通常与服务器系统中的物理CPU核心数量一致。此外,客户端到工作线程的映射在Memcached初始化期间静态建立。
如图5所示,工作线程由Libevent启动;Libevent 是 Linux 中 epoll系统调用的可移植网络协议封装,用于监控预建立连接(套接字)。工作线程将在 Libevent中等待事件,该事件对应于请求的到达。当事件发生时,将调用一个回调函数,并以文件描述符(fd)作为参数来处理该事件。在此情况下,文件描述符是网络连接的一个抽象标识。接收到 fd 后,工作线程从套接字读取数据并解码命令(读取并解析数据)。假设请求的是缓存项,线程会根据键计算哈希值,并执行哈希表查找,以确定与该键相关联的值数据在系统内存中的位置(请求处理)。
数据定位后,将其从系统内存中检索出来,并传回给请求客户端(发送响应)。此处理流程符合我们在第2.2节中描述的基线行为,即线程持续等待请求,CPU核心在请求到达时被唤醒。
由于基线Memcached是使用libevent实现的,主要挑战在于确定在哪里以及如何应用我们的动态睡眠方案。图6展示了我们提出的memcached实现的概览。我们分离了原始的工作线程,将其拆分为两个线程:libevent 线程和 请求处理 线程。
libevent 线程包含 libevent 包装器和动态睡眠计算器(DynSleep Calculator)。libevent 会监听传入的请求,并在请求到达时将请求插入到 请求处理 线程的队列中。动态睡眠计算器将根据第3.1节所述计算唤醒时间,并通过 Linux 提供的 timerfd API 在 libevent 中注册或更新一个定时器事件。当定时器到期后,动态睡眠计算器将通过 pthread_kill 发送唤醒信号,以唤醒 请求处理 线程。需要注意的是,当有事件到来时,libevent 仅提供相应的套接字文件描述符,表示已有数据准备就绪可供读取。在某些情况下,多个请求会在套接字中排队,并且这些数据将被一起读取,类似于批量到达的情况。为了计算相应的唤醒时间,我们需要在实际读取数据之前知道该批次中的请求数量。我们通过使用 IOCTL API 对套接字进行“预览”,获取批次的数据大小,再除以单个请求的平均大小,从而得到该批次中的请求数量,用于唤醒时间的计算。
在请求处理线程中,DynSleep Manager负责维护和监控队列。当发现队列中没有请求时,它会通知libevent线程中的动态睡眠计算器,并通过 sleep函数进入睡眠状态。同时,当接收到唤醒信号时,睡眠将被中断,核心将被唤醒,从队列中获取请求并进行处理,直到队列为空。
5. 评估
5.1 实验设置
我们使用两台多核机器,一台客户端服务器和一台请求处理服务器,通过以太网连接。客户端服务器将与请求处理服务器建立多个TCP连接,模拟多个客户端发送请求。每个客户端的请求间隔时间遵循指数分布,并进行缩放以观察不同流量负载对请求处理服务器的影响。
我们主要关注采用 Intel Xeon E5 2697-V2 12核处理器的请求处理服务器的行为。在实验中,超线程和睿频加速功能均被禁用。该处理器仅支持芯片级电压控制,但可通过 MSR 独立调节每核心频率。频率可在 1.2到2.7GHz 范围内以 100MHz步进 进行设置。除非另有说明,CPU频率均设为 2.7GHz。睡眠状态特性见表I。此外,该 Intel 处理器配备了用于 CPU核心 的片上能量传感器。通过 MSR,以 1千赫兹 的速率采集功耗结果。
在请求处理服务器中,我们同时运行3个Memcached实例,每个实例包含4个线程。这是针对已知的Memcached可扩展性问题 [2]的一种推荐解决方案。此外,请求处理线程到核心映射是固定的,以避免由Linux线程调度器引起的运行间差异[16]。对于我们的Memcached版本,所有libevent线程运行在一个核心上,而请求处理线程与中央处理器核心一一映射。我们将尾部延迟定义为95百分位数延迟;延迟目标设置为基准Memcached在80%负载下运行时的尾部延迟。
5.2 结果
为了展示我们DynSleep方案的有效性,我们将结果与四种电源管理方案进行比较:基线方案、DVFS、DFS和EP方案。我们未与PowerNap或DreamWeaver进行比较,因为它们基于能够以微秒级速度进入全服务器睡眠状态的假设的服务器。此外,我们观察到Memcached的空闲时段太短,无法被PowerNap利用。在本文中,我们将评估范围限制在实际的现实世界实现上。在基线方案中,CPU核心频率始终设置为最大值。在DVFS方案中,我们监控一个周期内的延迟,并在该周期结束时调整电压‐频率配置2。由于我们的实验平台不支持单核动态电压频率调节,我们通过在一个核心上以单线程运行应用程序并关闭所有其他核心来估算DVFS节能效果。然后将功耗结果按中央处理器的核心数量缩放,假设所有核心表现相同。
DFS方案与DVFS方案类似,不同之处在于我们仅改变每个核心的频率,而电压保持不变。EP方案代表理想化节能,假设功耗与负载完全成正比。
节能: 图7 报告了四种不同的电源管理方案在不同CPU负载下相对于基线方案的功耗节省情况。在低至中等负载(10~50 %)时,DynSleep的表现优于所有其他方案(EP除外),在高负载下与DVFS方案相当。在低至中等负载时,由于有更大的延迟余量可用,DynSleep能够高效地为CPU核心创建更长的空闲时段,使其进入深度睡眠状态。然而,随着负载增加,延迟余量和空闲时段减少,DynSleep只能使CPU核心进入浅层睡眠状态。但需要注意的是,由于缺乏每核电压控制,大多数商用服务器不支持DVFS方案。一个更现实的方案是DFS。DynSleep在所有情况下均显著优于DFS方案。此外,DynSleep实现的节能平均在EP的10%以内。由于睡眠状态转换开销的存在,CPU核心在进入/退出睡眠状态时必须消耗一定的时间和功耗,这使得DynSleep无法实现完美的能耗比例性。
延迟分布的变化:
图8显示了基线、动态频率调节(也代表动态电压频率调节2)和DynSleep方案在负载为0.3时的延迟分布。这些实验中,我们在固定负载下运行每种方案一分钟。
每种方案下的尾部延迟用圆圈标出,目标尾部延迟由红色虚线表示。我们可以看到,尽管存在较大的延迟余量(基线与目标尾部延迟之间约500微秒),但DFS方案(尾部延迟为448微秒)无法充分利用此余量。DFS方案会减慢请求处理速度,从而增加服务时间和排队延迟。然而,频率调节的动态范围限制了DFS在利用延迟余量和节能方面的有效性。我们的DynSleep方案通过动态推迟请求处理,进一步利用了这些机会,从而更好地利用了该余量并实现节能。需要注意的一点是,DynSleep的延迟累积分布函数(CDF)曲线中存在明显的 “拐点”。拐点前的平缓斜率是由于部分请求在前一个请求处理期间到达以及突发入站流量所致。在处理期间到达的请求不会受到CPU休眠带来的额外延迟影响,它们只需等待所有先前排队的请求完成处理即可。另一方面,在流量突发期间,唤醒时间主要由较晚到达的请求决定(例如图3中的R3)。因此,先前到达并排队的请求的等待时间更短,其延迟将远低于目标值。拐点后的陡峭斜率是由因DynSleep而排队等待的请求引起的。可以看出,DynSleep能够在不违反目标的情况下,将请求延迟分布的相当大一部分向目标尾部延迟偏移。
对负载变化的敏感性:
除了在稳态下满足目标尾部延迟(图8)外,DynSleep的设计还使其能够对输入负载的突然变化做出即时响应。由于唤醒时间在每次请求到达时刻都会更新,因此DynSleep能够立即响应请求间到达时间的变化。图9展示了DynSleep和动态频率调节在面对突发负载变化时的响应情况。
底部显示了输入负载,其在4秒内以阶梯形式增长,从0.2、0.3、0.5增加到0.7。顶部显示了两种方案的第95百分位延迟在100毫秒窗口内。首先,我们可以看到DFS方案在负载变化时以及高负载(0.5和0.7)期间会导致延迟尖峰。这是由于周期的高粒度所致。频率只能在周期结束时进行调整。因此,DFS对负载变化缺乏响应性,并频繁出现延迟违规。此外,在低负载(0.2和0.3)时,频率调节的限制导致尾部延迟过低,造成不必要的功耗浪费。相比之下,DynSleep能够在所有负载下实现稳定的尾部延迟。在低负载时,DynSleep选择更晚唤醒核心,使尾部延迟接近延迟边界,从而节省额外功耗。同时,得益于动态唤醒时间调整,它能够快速适应突发的负载变化。
6. 结论
我们提出了DynSleep,一种细粒度电源管理技术,通过智能地创建长时间空闲期并利用CPU深度睡眠状态来降低核心功耗。DynSleep采用了一种新颖的性能模型,以应对延迟敏感型应用程序行为中的不确定性。我们在Memcached中实现了DynSleep,并在真实的多核服务器上验证了该方法的有效性。
实验结果表明,我们的DynSleep最多可实现65%的节能。
2022

被折叠的 条评论
为什么被折叠?



