Chapter8 性能

目录

性能一般场景

性能策略

控制资源需求

管理资源

调度策略

性能策略在道路系统设计中的应用

性能设计检查表

总结


性能一盎司胜过承诺一吨。

——梅·韦斯特

这是关于时间的问题。性能,也就是说:这关乎时间以及软件系统满足时间要求的能力。当事件发生时,中断、消息、来自用户或其他系统的请求,或时钟事件标记时间的流逝,系统或系统的某个部分必须及时做出响应。描述可能发生的事件(以及它们可能发生的时间)以及系统或元素对这些事件的基于时间的响应,这才是讨论性能的实质。

基于Web的系统事件以用户的请求形式出现(数量可达数百万甚至数千万),通过他们的客户端,比如Web浏览器。在内燃机控制系统中,事件来自操作员的控制和时间的流逝;系统必须控制点火时间,确保汽缸处于正确的位置,并调整燃料混合以最大化动力和效率,同时尽量减少污染。

对于基于Web的系统,期望的响应可以表示为每分钟可以处理的事务数量。对于发动机控制系统,响应可能是点火时间允许的变差。在每种情况下,事件到达的模式和响应的模式可以被特征化,而这种特征化构成了构建性能场景的语言。

在软件工程的大部分历史中,性能一直是系统架构的驱动因素。因此,它经常会妥协其他所有品质的实现。随着硬件的性价比不断下降和软件开发成本不断上升,其他品质已经成为性能的重要竞争对手。

尽管如此,所有系统都有性能要求,即使它们没有明确表达出来。例如,文字处理工具可能没有明确的性能要求,但毫无疑问,每个人都会同意在屏幕上看到输入的字符之前等待一个小时(或一分钟,或一秒)是不可接受的。性能继续是所有软件的根本重要的质量属性

性能通常与可伸缩性相关,即提高系统的工作能力,同时仍然保持良好的性能。从技术上讲,可伸缩性是使系统易于以特定方式进行更改的过程,因此它是一种可修改性。此外,在第12章中,我们明确讨论了可伸缩性。

性能一般场景

一个性能场景以一个事件到达系统开始。正确响应事件需要消耗资源(包括时间)。在这个过程中,系统可能同时为其他事件提供服务。

并发
并发是架构师必须理解的重要概念之一,但却是计算机科学课程中教授得最少的概念之一。并发是指同时发生的操作。例如,假设有一个线程执行以下语句:
X = 1;
x++;
还有另一个线程执行相同的语句。在这两个线程都执行了这些语句之后,x 的值是多少?它可以是2或3。我留给你来弄清楚值为3是如何发生的,或者说,我应该说是交替执行给你看?

并发发生在系统创建新线程的任何时候,因为线程根据定义是独立的控制序列。你的系统上支持多任务处理通过独立线程。多用户可以通过线程的使用同时在你的系统上得到支持。并发还发生在你的系统在多个处理器上执行时,无论这些处理器是否单独封装或是多核处理器。此外,当你的系统使用并行算法、并行基础设施(如map-reduce)或NoSQL数据库,或者使用各种并发调度算法时,你必须考虑并发。换句话说,并发是在许多方面提供给你的工具。

当你有多个CPU或可以利用等待状态时,并发是一件好事。允许操作并行进行可以提高性能,因为一个线程中引入的延迟允许处理器在另一个线程上继续执行。但由于刚刚描述的交替现象(称为竞争条件),并发也必须由架构师仔细管理。

正如示例所示,当有两个控制线程并且存在共享状态时,竞争条件可能发生。并发的管理通常归结为管理状态的共享方式。防止竞争条件的一种技术是使用锁来强制对状态的顺序访问。另一种技术是根据执行代码的线程将状态进行分区划分。也就是说,在我们的示例中,如果有两个 x 的实例,那么 x 不会被两个线程共享,也不会出现竞争条件。

竞争条件是最难发现的错误类型之一;这种错误的发生是零星的,依赖于(可能是微小的)时间差异。我曾经在一个操作系统中遇到过一个竞争条件,我无法追踪。我在代码中放了一个测试,以便下一次发生竞争条件时触发调试过程。花了一年多的时间才能重新发现错误,从而确定了原因。

不要让与并发相关的困难阻止你使用这个非常重要的技术。只需使用它,并了解你必须仔细识别代码中的关键部分,并确保竞争条件不会在这些部分发生。

事件可以按可预测的模式或数学分布到达,也可以是不可预测的。事件的到达模式可分为周期性随机性零星性

  • 周期性事件以规律的时间间隔可预测地到达。例如,事件可能每隔10毫秒到达一次。周期性事件的到达最常见于实时系统。
  • 随机到达意味着事件按照某种概率分布到达。
  • 零星事件按照既不周期性也不随机的模式到达。然而,在某些情况下,即使这些事件也可以被表征。例如,我们可能知道在一分钟内最多会发生600个事件,或者在任何两个事件到达之间至少会有200毫秒的时间间隔。这可能描述了一个事件对应于人类用户键盘击键的系统。即使我们不知道单个事件何时会到达,这些都是有用的特征。

系统对刺激的响应可以通过以下方式进行衡量

  • 延迟刺激到达系统对其的响应之间的时间。
  • 处理中的截止时间:例如,引擎控制器中,燃料应该在气缸处于特定位置时点燃,从而引入了处理的截止时间。
  • 系统的吞吐量:通常表示系统在单位时间内可以处理的事务数量
  • 响应的抖动:即延迟的允许变化
  • 未处理率:由于系统繁忙而未处理的事件数量。

根据这些考虑,现在我们可以描述性能一般场景的各个部分:

  • 刺激源:刺激可以来自外部(可能是多个)或内部来源。
  • 刺激:刺激是事件的到达。到达模式可以是周期性的、随机的或零星的,可以用数字参数进行表征
  • 构件:构件是系统或其一个或多个组成部分
  • 环境:系统可以处于不同的运行模式,如正常紧急高负荷过载
  • 响应:系统必须处理到达的事件。这可能会导致系统环境的变化(例如,从正常模式到过载模式)。
  • 响应度量:响应度量包括处理到达事件所需的时间(延迟截止时间)、这个时间的变化(抖动)、在特定时间间隔内可以处理的事件数量(吞吐量)或无法处理的事件的特征(未处理率)。

性能的一般场景总结在表8.1中。

                       

性能策略

性能策略的目标是在一定的基于时间的限制内对系统到达的事件生成响应。事件可以是单个事件或一系列事件,是触发进行计算的信号。性能策略控制了生成响应的时间,如图8.2所示。

在事件到达后,但在系统对其作出响应之前的任何时刻,要么系统正在工作以响应该事件要么出于某种原因处理被阻塞。这导致了响应时间的两个基本因素:处理时间(系统正在工作以响应时)和阻塞时间(系统无法响应时)。

  • 处理时间。处理消耗资源,这需要时间。事件通过一个或多个组件的执行来处理,这些组件的消耗时间是资源硬件资源包括CPU、数据存储、网络通信带宽和内存软件资源包括系统设计下定义的实体。例如,必须管理缓冲区,对关键部分 1 的访问必须顺序进行。

1. 临界区是多线程系统中的代码部分,在该部分最多只能有一个线程活动

例如,假设一个组件生成了一条消息。它可能被放置在网络上,然后到达另一个组件。然后它被放置在缓冲区;以某种方式进行变换;按某种算法进行处理;进行输出的变换;放置在输出缓冲区;并继续发送到另一个组件、另一个系统或某个执行者。这些步骤消耗资源和时间,并为处理事件的整体延迟做出贡献

不同的资源在其利用率接近容量时会有不同的行为,即当它们变得饱和时。例如,当CPU负载变得更重时,性能通常会逐渐下降。另一方面,当你开始耗尽内存时,在某个时刻页面交换会变得压倒性,性能会突然崩溃。

  • 阻塞时间。计算可能会因为争用某个需要的资源资源不可用计算依赖于尚不可用的其他计算结果而被阻塞:
  • 争用资源。许多资源一次只能由一个客户端使用。这意味着其他客户端必须等待以访问这些资源。图8.2显示了到达系统的事件。这些事件可以是单个流或多个流。多个流竞争相同的资源,或者相同流中的不同事件竞争相同的资源,都会导致延迟。资源争用越多,引入延迟的可能性就越大。
  • 资源的可用性。即使没有争用,如果资源不可用,计算也无法继续进行。资源的不可用可能是由于资源脱机组件故障或其他原因引起的。无论如何,您必须确定资源不可用可能会对整体延迟产生显著影响的地方。我们的一些策略旨在应对这种情况。
  • 对其他计算的依赖。计算可能必须等待,因为它必须与另一个计算的结果同步,或者因为它正在等待它启动的计算的结果。如果一个组件调用另一个组件并必须等待该组件的响应,如果被调用的组件位于网络的另一端(而不是与之同处于同一处理器上),时间可能是显著的。

有了这个背景,我们可以将注意转向我们的策略类别。我们可以减少对资源的需求,或者使我们手头的资源更有效地处理需求:

  • 控制资源需求:这个策略在需求方面操作,以减少对必须为事件提供服务的资源的需求
  • 管理资源:这个策略在响应方面操作,以使手头的资源更有效地处理被提出的需求

控制资源需求

提高性能的一种方式是仔细管理资源需求。这可以通过降低事件处理数量(通过强制采样率)或限制系统响应事件的速率来实现。此外,还有一些技术可以确保你所拥有的资源得到明智的应用:

  • 管理采样率:如果可能降低对环境数据流进行捕获的采样频率,那么需求就可以降低,通常会伴随一定的信息丢失。这在信号处理系统中很常见,例如,可以选择具有不同采样率和数据格式的不同编解码器。这个设计选择是为了保持可预测的延迟水平;你必须决定是否更喜欢具有较低保真度但一致的数据流,而不是丢失数据包。
  • 限制事件响应:当离散事件以过快的速度到达系统(或元素),以至于无法及时处理这些事件时,这些事件必须排队等待处理。因为这些事件是离散的,通常不希望对它们进行“降采样”。在这种情况下,您可以选择仅处理一定的最大速率的事件,从而在实际处理事件时确保更可预测的处理。这个策略可以由队列大小或处理器利用率的度量超过某个警告级别来触发。如果采用这种策略,而且不能丢失任何事件,则必须确保队列足够大,以处理最坏情况。另一方面,如果选择丢弃事件,那么需要选择处理这种情况的策略:是记录丢弃的事件,还是简单地忽略它们?是否通知其他系统、用户或管理员?
  • 优先事件:如果不是所有事件都同等重要,您可以实施一个根据为其提供服务的重要性对事件进行排名的优先级方案。如果在事件发生时没有足够的资源可用于为其提供服务,低优先级事件可能会被忽略。忽略事件消耗最少的资源(包括时间),因此与一直为所有事件提供服务的系统相比,性能会更好。例如,建筑管理系统可能会发出各种警报。像火警这样具有生命威胁的警报应该比像房间太冷这样的信息性警报具有更高的优先级。
  • 减少开销中介的使用(如我们在第7章中看到的对可修改性非常重要)会增加处理事件流所消耗的资源,因此去除它们会提高延迟。这是可修改性/性能权衡的经典选择。关注点分离可修改性的另一个关键点,也可能会增加处理事件所需的开销,因为它可能导致一个事件由一系列组件而不是单个组件来处理。上下文切换和组件间通信成本会积累,特别是当组件位于网络上的不同节点时。减少计算开销的策略是共同放置资源。共同放置可能意味着将协作组件放在同一处理器上,以避免网络通信的时间延迟;它还可能意味着将资源放在同一运行时软件组件中,以避免子例程调用的开销。减少计算开销的一个特殊情况是定期清理效率低下的资源。例如,哈希表和虚拟内存映射可能需要重新计算和重新初始化。另一个常见的策略是执行单线程服务器(为了简单和避免争用)并将工作负载分担在它们之间
  • 限制执行时间:设置响应事件使用的执行时间的上限。对于迭代的、数据相关的算法,限制迭代次数是限定执行时间的一种方法。通常代价是计算的准确性降低。如果采用这种策略,您将需要评估其对准确性的影响,看看结果是否“足够好”。这种资源管理策略通常与管理采样率策略一起使用
  • 增加资源效率改进关键领域的算法将减少延迟。

管理资源

即使资源需求不可控,这些资源的管理是可控的。有时,一个资源可以用来交换另一个资源。例如,中间数据可以根据时间和空间资源的可用性保留在缓存中,也可以根据需要重新生成。这个策略通常适用于处理器,但也适用于其他资源,如磁盘。以下是一些资源管理策略:

  • 增加资源:更快的处理器、额外的处理器、额外的内存和更快的网络都有降低延迟的潜力。成本通常是资源选择的一个考虑因素,但增加资源绝对是降低延迟的策略,在许多情况下也是获得即时改进的最便宜的方法。
  • 引入并发性:如果请求可以并行处理,可以减少阻塞时间。并发可以通过在不同线程上处理不同的事件流或创建额外的线程来处理不同的活动集来引入。一旦引入了并发性,可以使用调度策略来实现您认为合适的目标。不同的调度策略可以最大程度地提高公平性(所有请求获得相等的时间)、吞吐量(最短完成时间)或其他目标。(见边栏。)
  • 维护计算的多个副本:客户端-服务器模式中的多个服务器是计算的副本。副本的目的是减少如果所有计算都在单个服务器上进行会发生的争用。负载均衡器是一种分配新工作给可用的复制服务器之一的软件,分配的标准各不相同,但可以简单地是轮询或将下一个请求分配给最空闲的服务器。
  • 维护数据的多个副本:缓存是一种策略,涉及在具有不同访问速度的存储上保留数据的副本(可能是另一副本的子集)。不同的访问速度可能是固有的(内存与二级存储)或可能是由于需要进行网络通信。数据复制涉及保持数据的独立副本,以减少多个同时访问引起的争用。因为被缓存或复制的数据通常是现有数据的副本,因此保持这些副本的一致性和同步成为系统必须承担的责任。另一个责任是选择要缓存的数据。一些缓存仅仅通过保留最近请求的内容来工作,但也可以根据行为模式来预测用户未来的请求,并在用户发出请求之前开始计算或预取必要的数据,以满足这些请求。
  • 限制队列大小:这控制了最大排队到达的数量,因此也控制了处理到达的资源。如果采用这个策略,需要制定一个关于队列溢出时发生什么以及丢失事件是否可以不响应的策略。这个策略通常与限制事件响应策略一起使用。
  • 调度资源:每当资源存在争用时,都必须进行资源调度。处理器被调度,缓冲区被调度,网络被调度。您的目标是了解每个资源使用的特性,并选择与之兼容的调度策略。(见边栏。)

性能策略总结在图8.3中。

调度策略

调度策略在概念上分为两部分:优先级分配和分派。所有调度策略都分配优先级。在某些情况下,分配可以像先进先出(FIFO)那样简单。在其他情况下,它可能与请求的截止日期或其语义重要性有关。竞争调度的标准包括最佳资源利用、请求重要性、最小化使用的资源数量、最小化延迟、最大化吞吐量、防止饥饿以确保公平性等等。您需要意识到这些可能相互冲突的标准以及所选策略对满足这些标准的影响。

只有当分配给其的资源可用时,高优先级的事件流才能被分派。有时这依赖于抢占资源的当前用户。可能的抢占选项如下:可以随时发生,只能在特定的抢占点发生,正在执行的进程不能被抢占。一些常见的调度策略包括以下内容:

  • 先进先出:FIFO队列将资源的所有请求都视为相等,并依次满足它们。FIFO队列的一个可能性是,一个请求将被卡在另一个请求后面,后一个请求需要很长时间才能生成响应。只要所有请求都确实是相等的,这不是问题,但如果某些请求比其他请求的优先级更高,这就是一个问题。
  • 固定优先级调度:固定优先级调度为每个资源请求源分配特定的优先级,并按该优先级顺序分配资源。这个策略确保更好地为更高优先级的请求提供服务。但它允许较低优先级但重要的请求需要花费任意长的时间来提供服务,因为它被卡在一系列更高优先级的请求后面。三个常见的优先级分配策略如下:
  • 语义重要性:每个流根据生成它的任务的领域特征静态地分配优先级。
  • 截止日期单调:截止日期单调。截止日期单调是一种将较短截止日期的流分配更高优先级的静态优先级分配策略。当要对具有实时截止日期的不同优先级的流进行调度时,使用这种调度策略。
  • 频率单调:频率单调是用于周期性流的静态优先级分配策略,它将较短周期的流分配更高的优先级。这种调度策略是截止日期单调的一个特殊情况,但更为知名,更有可能得到操作系统的支持。
  • 动态优先级调度:策略包括:
  • 轮询:轮询是一种调度策略,对请求进行排序,然后在每个分配可能性时将资源分配给该顺序中的下一个请求。轮询的一个特殊形式是循环执行,其中分配可能性在固定时间间隔内发生。
  • 最早截止日期优先:最早截止日期优先。最早截止日期优先是基于具有最早截止日期的待处理请求分配优先级的策略。
  • 最小剩余松弛时间:这个策略将最高优先级分配给剩余执行时间和工作截止日期时间之间的差值最小的任务。
  • 对于单处理器和可抢占的进程(即可以暂停一个任务的处理以提供服务于截止日期接近的任务),既最早截止日期策略又最小剩余松弛策略都是最优的。也就是说,如果可以安排一组进程以满足所有截止日期,那么这些策略将能够成功地安排该组。
  • 静态调度:循环执行调度是一种调度策略,其中抢占点和资源分配的顺序是离线确定的。这样可以避免调度器的运行时开销。

性能策略在道路系统设计中的应用

策略是通用的设计原则。为了说明这一点,请考虑您所在地区的道路和高速公路系统的设计。交通工程师采用一堆设计“技巧”来优化这些复杂的系统的性能,其中性能有许多衡量指标,比如吞吐量(从郊区到足球场每小时有多少辆车)、平均情况下的延迟(从您的家到市区平均需要多长时间)、以及最坏情况下的延迟(紧急车辆把您送到医院需要多长时间)。这些“技巧”都是我们的老朋友,也就是策略。

让我们考虑一些例子:

  • 管理事件率。高速公路入口匝道上的红绿灯只允许车辆在固定的时间间隔内进入高速公路,车辆必须在匝道上等待(排队)等待他们的机会。
  • 设置事件优先级。开着警灯和警笛的救护车和警车比普通市民的优先级更高;一些高速公路拥有高占有率车辆(HOV)车道,为两名或两名以上乘员的车辆提供优先权。
  • 保持多份副本。在现有道路上增加交通车道,或者建造平行路线。
  • 此外,系统的用户还可以采用一些策略:
  • 增加资源。例如,购买一辆法拉利。其他一切条件相同的情况下,驾驶员熟练的最快车辆可以在开放道路上更快地将您送到目的地。
  • 增加效率。寻找比当前路线更快和/或更短的新路线。
  • 减少计算开销。您可以开车靠近前面的车辆,或者可以将更多的人拥挤进同一辆车(即拼车)。

这次讨论的要点是什么?用格特鲁德·斯坦的话来说:性能就是性能就是性能。工程师们几个世纪以来一直在分析和优化系统,试图改善其性能,并且一直在采用相同的设计策略来实现这一点。因此,当您尝试提高计算机系统的性能时,您正在应用经过充分“路考”的策略。

性能设计检查表

表格 8.2 是一个用于支持性能设计和分析过程的检查表。

总结

性能是关于在特定类型的需求面前管理系统资源,以实现可接受的时间行为。性能可以根据互动式系统和嵌入式实时系统的吞吐量和延迟来衡量,尽管在互动式系统中通常更重要的是吞吐量,而在嵌入式系统中更重要的是延迟。

通过减少需求或更合适地管理资源,可以改善性能。减少需求将有降低保真度或拒绝为一些请求提供服务的副作用。更合适地管理资源可以通过调度、复制或增加可用资源来实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值