
如果你给一个人看一段代码你将折磨他一天如果你教一个人写一段代码你将折磨他一辈子。引言在本章让我们通过介绍低延迟应用开启这段学习之旅。在这一章中我们将首先了解对延迟敏感和延迟关键型应用的行为及需求。我们会明白应用延迟对那些依赖快速且严格响应时间的企业有着巨大的商业影响。我们还将探讨为什么C是低延迟应用开发中最受青睐的编程语言之一。本书的很大一部分内容是用C从零开始构建一个完整的低延迟电子交易系统。因此本章将帮助你理解使用C的动机以及是什么让它成为低延迟应用领域最受欢迎的语言。我们也会介绍不同商业领域中一些重要的低延迟应用。这样做的部分目的是让你了解到在不同的商业领域对于那些对响应时间敏感的用例来说延迟确实至关重要。另一部分目的是找出这些应用在行为、期望、设计和实现方面的相似之处。尽管它们解决的是不同的商业问题但这些应用的低延迟需求通常是基于相似的技术设计和实现原则构建的。在本章中我们将涵盖以下主题理解对延迟敏感应用的需求理解为什么C是首选编程语言介绍一些重要的低延迟应用为了有效地构建超低延迟应用我们首先应该理解本书后续会用到的术语和概念。我们还应该明白为什么C成为了大多数低延迟应用开发的不二之选。时刻牢记低延迟对业务的影响也很重要因为我们构建低延迟应用的目的是为了提升企业的盈利。本章将讨论这些内容以便在深入学习本书后续的技术细节之前为你打下良好的基础。理解对延迟敏感应用的需求在本节中我们将讨论一些概念这些概念有助于理解哪些指标对延迟敏感应用至关重要。首先让我们明确延迟的定义以及什么是延迟敏感应用。延迟被定义为从任务开始到任务完成之间的时间延迟。根据定义任何处理或工作都会产生一定的开销或延迟——也就是说除非系统完全不工作否则没有系统的延迟为零。这里重要的一点是有些系统的延迟可能只有极小的几毫秒而且对额外一微秒的延迟容忍度可能很低。低延迟应用是指那些尽可能快速地执行任务并做出响应或返回结果的应用。关键在于反应延迟是这类应用的一个重要标准较高的延迟可能会降低性能甚至使应用完全无法使用。另一方面当这类应用能够达到预期的低延迟时它们可以在竞争中脱颖而出以最高速度运行实现最大吞吐量或者提高生产力并改善用户体验——具体效果取决于应用本身和业务场景。低延迟既可以被看作是一个定量的术语也可以被看作是一个定性的术语。定量方面很容易理解但定性方面可能并不那么明显。根据不同的上下文架构师和开发人员在某些情况下可能愿意接受较高的延迟但在另一些情况下可能连额外一微秒的延迟都无法接受。例如如果用户刷新网页或等待视频加载几秒钟的延迟是可以接受的。然而一旦视频加载完成并开始播放再出现几秒钟的渲染或显示延迟就会对用户体验产生负面影响。一个极端的例子是高速金融交易系统在这个系统中几微秒的延迟就可能导致一家公司盈利或完全失去竞争力。在接下来的小节中我们将介绍一些适用于低延迟应用的术语。充分理解这些术语非常重要因为在后续关于低延迟应用的讨论中我们会经常提到这些概念。接下来要讨论的概念和术语用于区分不同的延迟敏感应用、测量延迟的方法以及这些应用的需求。理解延迟敏感型与延迟关键型应用“延迟敏感应用latency-sensitive applications”和“延迟关键型应用latency-critical applications”这两个术语之间存在着微妙但重要的区别。延迟敏感应用是指随着性能延迟的降低其商业影响或盈利能力会有所提升的应用。也就是说在较高的性能延迟下该系统可能仍然能够运行并可能盈利但如果延迟降低其盈利能力会显著提高。这类应用的例子包括操作系统OSes、网页浏览器、数据库等等。另一方面延迟关键型应用是指如果性能延迟高于某个阈值就会完全失效的应用。关键在于延迟敏感应用在较高延迟下可能只是部分盈利能力受损而延迟关键型应用在足够高的延迟下则会完全无法运行。这类应用的例子有交通控制系统、金融交易系统、自动驾驶汽车以及一些医疗设备。测量延迟在本节中我们将讨论测量延迟的不同方法。这些方法的真正区别在于如何定义处理任务的开始时间和结束时间。另一种区分方法是看测量的单位——时间是最常用的单位但在某些情况下如果涉及到指令级别的测量CPU时钟周期也可以使用。接下来让我们看看不同的测量方法但首先我们给出一个通用的服务器 - 客户端系统示意图这里暂不深入探讨具体的用例或传输协议。这是因为测量延迟的方法具有通用性适用于许多具有这种服务器 - 客户端架构的不同应用。图1.1 一个带有不同跳数时间戳的通用服务器 - 客户端系统我们展示这个示意图是因为在接下来的几个小节中我们将定义并理解从服务器到客户端再返回服务器的往返路径中不同跳数之间的延迟。首字节时间首字节时间Time to first byte是指从发送方发送请求或响应的第一个字节开始到接收方接收到第一个字节为止所经过的时间。这通常但并非绝对适用于对延迟敏感的数据传输操作的网络链路或系统。在图1.1中首字节时间是T4和T3之间的差值。往返时间往返时间Round-trip timeRTT是指一个数据包从一个进程传输到另一个进程再加上响应数据包返回原始进程所花费的时间总和。同样这通常但并非绝对用于衡量服务器和客户端进程之间来回的网络流量但也可以用于一般的两个进程之间的通信。默认情况下RTT包括服务器进程读取、处理并响应用户发送的请求所花费的时间——也就是说RTT通常包含服务器处理时间。在电子交易的场景中真正的RTT延迟基于三个部分第一信息从交易所到达参与者所需的时间第二执行算法分析信息并做出决策所需的时间最后决策到达交易所并由匹配引擎处理所需的时间我们将在本书最后一节“分析和提高性能”中进一步讨论这个问题。从报价到交易时间从报价到交易时间Tick-to-tradeTTT与RTT类似是电子交易系统中最常用的术语之一。TTT被定义为从一个数据包通常是市场数据包首次到达参与者的基础设施交易服务器到参与者完成对该数据包的处理并向交易所以外发送数据包订单请求的时间。因此TTT包括交易基础设施读取数据包、处理它、计算交易信号、生成相应的订单请求并将其发送出去所花费的时间。将数据包发送出去通常意味着向网络套接字写入数据。我们将在本书最后一节“分析和提高性能”中再次讨论这个主题并进行更深入的探讨。在图1.1中TTT是T3和T2之间的差值。CPU时钟周期CPU时钟周期基本上是CPU处理器能够完成的最小工作增量。实际上它们是驱动CPU处理器的振荡器两次脉冲之间的时间量。测量CPU时钟周期通常用于在指令级别测量延迟——也就是说在处理器的极低级别进行测量。C既是一种低级语言也是一种高级语言它让你可以根据需要接近硬件同时也提供了类、模板等高级抽象。但一般来说C开发人员不会花太多时间处理极低级别或可能的汇编代码。这意味着编译后的机器代码可能与C开发人员预期的不完全一样。此外根据编译器版本、处理器架构等因素的不同可能会有更多的差异来源。因此对于对性能极为敏感的低延迟代码工程师通常会测量执行了多少条指令以及执行这些指令需要多少个CPU时钟周期。这种级别的优化通常是与内核级优化并列的最高级别优化。现在我们已经了解了在不同应用中测量延迟的一些不同方法在下一节中我们将看看一些延迟汇总指标以及它们在不同场景下的重要性。区分不同的延迟指标特定延迟指标相对于其他指标的相对重要性取决于应用程序和业务本身。例如像自动驾驶汽车软件系统这样对延迟要求极高的应用程序比起平均延迟它更关注峰值延迟。低延迟的电子交易系统通常更在意平均延迟和较小的延迟方差而非峰值延迟。由于应用程序的性质和用户需求视频流和播放应用程序一般会优先考虑高吞吐量而非更低的延迟方差。吞吐量与延迟在研究这些指标之前我们首先需要清楚地理解 “吞吐量throughput” 和 “延迟latency” 这两个术语之间的区别。它们非常相似常被混用但实际上不应如此。吞吐量指的是在特定时间段内完成的工作量而延迟是指单个任务完成的速度有多快。为了提高吞吐量通常的做法是引入并行处理并增加计算、内存和网络资源。请注意虽然单个任务的处理速度可能不会尽可能快但总体而言经过一段时间后会完成更多任务。这是因为在并行处理时每个单独的任务处理时间可能比低延迟设置下更长但并行性提高了一组任务的整体吞吐量。另一方面延迟是针对每个单独任务从开始到结束进行测量的即使总体执行的任务数量较少。平均延迟平均延迟基本上是系统预期的平均响应时间。它就是所有延迟测量值的平均值。这个指标包含了较大的异常值所以对于性能延迟范围较大的系统来说它可能是一个不太准确的指标。中位数延迟中位数延迟通常是衡量系统预期响应时间的更好指标。由于它是延迟测量值的中位数所以排除了较大异常值的影响。因此有时它比平均延迟指标更受青睐。峰值延迟对于那些单个性能异常值可能对系统造成严重影响的系统来说峰值延迟是一个重要指标。较大的峰值延迟值也会显著影响系统的平均延迟指标。延迟方差对于那些要求延迟尽可能具有确定性的系统性能延迟的实际方差是一个重要指标。在预期延迟相当可预测的情况下这一点尤为重要。对于延迟方差较低的系统平均延迟、中位数延迟和峰值延迟预计都非常接近。对延迟敏感型应用程序的要求在本节中我们将正式描述延迟敏感型应用程序的行为以及这些应用程序预期遵循的性能特征。显然延迟敏感型应用程序需要低延迟性能但在这里我们将尝试探讨 “低延迟” 这个术语的细微差别并讨论一些不同的看待方式。正确性和稳健性当我们想到延迟敏感型应用程序时通常会认为低延迟是这类应用程序最重要的方面。但实际上这类应用程序的一个重要要求是正确性这里指的是极高水平的稳健性和容错能力。直观地看这个观点完全合理这些应用程序要想成功就需要极低的延迟这意味着它们也需要有非常高的吞吐量需要处理大量的输入并产生大量的输出。因此系统需要达到接近100% 的正确性并且要非常稳健这样应用程序才能在其业务领域取得成功。此外随着应用程序在生命周期中的增长和变化正确性和稳健性要求也需要得到保持。平均低延迟这是我们考虑延迟敏感型应用程序时最明显的要求。为了使应用程序或业务整体取得成功预期的反应或处理延迟需要尽可能低。在这里我们关注平均和中位数性能延迟并希望它们尽可能低。从设计角度来看这意味着系统不能有太多的异常值或极高的性能延迟峰值。峰值延迟上限我们使用 “峰值延迟上限capped peak latency” 这个术语来表示应用程序可能遇到的最大延迟需要有一个明确的上限。这种要求对所有延迟敏感型应用程序都很重要对延迟关键型应用程序尤为重要。但即使在一般情况下少数情况下出现极高性能延迟的应用程序通常也会破坏系统的性能。这实际上意味着应用程序需要在低延迟期间内处理任何输入、场景或事件序列。当然处理非常罕见和特定场景的性能可能比最常见情况要高得多但关键是它不能是无限制的或不可接受的。可预测的延迟——低延迟方差有些应用程序更希望预期的性能延迟是可预测的即使这意味着如果平均延迟指标比可能的情况稍高一些也要做出一定的牺牲。这实际上意味着这类应用程序会确保对于各种不同的输入或事件预期的性能延迟方差尽可能小。实现零延迟方差是不可能的但可以在数据结构、算法、代码实现和设置方面做出一些选择尽可能地将其最小化。高吞吐量如前所述低延迟和吞吐量相关但并不相同。因此一些需要尽可能高吞吐量的应用程序在设计和实现上可能会有所不同以实现吞吐量最大化。关键在于最大化吞吐量可能会以牺牲平均性能延迟或增加峰值延迟为代价。在本节中我们介绍了适用于低延迟应用程序性能的概念以及这些指标对业务的影响。在本书后面讨论我们构建的应用程序的性能时会用到这些概念。接下来我们将进一步探讨可用于低延迟应用程序开发的编程语言。我们将讨论支持低延迟应用程序的语言的特点并理解为什么在开发和优化延迟敏感型应用程序方面C 会名列前茅。理解为什么C是首选编程语言在开发低延迟应用程序时有几种高级语言可供选择如Java、Scala、Go和C。在本节中我们将讨论为什么C是低延迟应用程序中最受欢迎的语言之一。我们将探讨C语言的几个特性这些特性支持构建大型代码库所需的高级语言结构。C的强大之处在于它还提供了与C语言类似的底层访问能力以支持高度的控制和优化。编译型语言C是一种编译型语言而非解释型语言。编译型语言是指将源代码翻译成可在特定架构上运行的机器码二进制文件的编程语言。C、C、Erlang、Haskell、Rust和Go都是编译型语言的例子。与编译型语言相对的是解释型语言。解释型语言的不同之处在于程序由解释器运行解释器逐行读取源代码并执行每个命令。Ruby、Python和JavaScript是解释型语言的一些例子。解释型语言本质上比编译型语言慢因为与编译型语言在编译时将代码翻译成机器指令不同解释型语言是在运行时将代码解释成机器指令。不过随着即时编译技术的发展解释型语言的速度差距已经没有那么大了。对于编译型语言代码已经针对目标硬件预先构建好了因此在运行时无需额外的解释步骤。由于C是编译型语言它赋予开发者对硬件的很多控制权。这意味着有能力的开发者可以优化诸如内存管理、CPU使用、缓存性能等方面。此外由于编译型语言在编译时就被转换为针对特定硬件的机器代码所以可以在很大程度上进行优化。因此一般来说编译型语言尤其是C执行速度更快、效率更高。更接近硬件——低级语言与其他流行的编程语言如Python、Java等相比C是低级语言因此它与硬件极为接近。当软件与运行它的目标硬件紧密耦合甚至在需要底层支持的情况下这一点尤其有用。与硬件极为接近还意味着用C构建系统具有显著的速度优势。特别是在像高频交易HFT这样的低延迟应用程序中几微秒的差异都可能产生巨大影响C通常是行业内公认的黄金标准。我们将讨论一个例子说明与硬件更接近是如何帮助C相比Java等其他语言提升性能的。C/C中的指针是内存中对象的实际地址。因此软件可以直接访问内存和内存中的对象无需额外的抽象而这些抽象会降低速度。不过这也意味着应用程序开发者通常必须显式地管理对象的创建、所有权、销毁和生命周期而不能像在Python或Java中那样依赖编程语言来管理这些事情。C接近硬件的一个极端例子是它可以直接从C语句中调用汇编指令——我们将在后面的章节中看到这样的示例。资源的确定性使用对于低延迟应用程序来说高效地使用资源至关重要。嵌入式应用程序也常用于实时应用场景在时间和内存资源方面尤其有限。在像Java和Python这类依赖自动垃圾回收的语言中存在不确定性因素也就是说垃圾回收器可能会不可预测地导致性能出现较大延迟。此外对于内存非常有限的系统像C和C这样的低级语言可以执行一些特殊操作比如通过指针将数据放置在内存的自定义段或地址中。在C和C这类语言中程序员负责显式地创建、管理和释放内存资源从而实现对资源的确定性和高效使用。速度与高性能正如我们之前讨论过的C比大多数其他编程语言速度更快。它还提供出色的并发和多线程支持。显然在开发对延迟敏感甚至延迟关键的低延迟应用程序时这是另一个显著优势。在负载繁重的服务器相关应用程序中如Web服务器、应用服务器、数据库服务器、交易服务器等也常常会有这样的需求。C的另一个优势在于其编译时优化能力。C和C支持宏、预处理指令、constexpr说明符以及模板元编程等特性。这些特性使我们能够将大部分处理工作从运行时转移到编译时。基本上这意味着在构建机器码二进制文件时通过将大量处理工作放在编译步骤中我们可以最大限度地减少关键代码路径在运行时的工作量。在后面构建完整的电子交易系统的章节中我们将深入讨论这些特性届时它们的优势将一目了然。语言结构和特性C语言本身是灵活性和丰富特性的完美结合。它为开发者提供了很大的自由度开发者可以利用这一点对应用程序进行底层优化。同时它也提供了许多高级抽象可用于构建非常庞大、功能丰富、通用且可扩展的应用程序并且在需要时仍能保持极低的延迟。在本节中我们将探讨一些C特有的语言特性这些特性使其在底层控制和高级抽象方面独具优势。可移植性首先C具有高度的可移植性可以构建能够针对多种不同操作系统、平台、CPU架构等进行编译的应用程序。由于它不需要因平台而异的运行时解释器所以所需做的就是在编译时构建正确的二进制文件这相对简单并且最终部署的二进制文件可以在任何平台上运行。此外我们已经讨论过的一些其他特性比如能够在低内存和性能较弱的CPU架构上运行并且无需垃圾回收使其比一些其他高级语言更具可移植性。编译器优化我们已经讨论过C是一种编译型语言这使得它天生比解释型语言速度更快因为它不会产生额外的运行时开销。由于开发者的完整源代码会被编译成最终的可执行二进制文件编译器有机会对所有对象和代码路径进行全面分析。这就使得在编译时进行高度优化成为可能。现代编译器与现代硬件紧密协作生成经过惊人优化的机器码。关键在于开发者可以专注于解决业务问题假设C开发者能力足够编译后的程序在无需开发者投入大量时间和精力的情况下仍能进行高度优化。由于C还允许直接内联汇编代码这为开发者提供了更大的机会与编译器协作生成高度优化的可执行文件。静态类型在编程语言的类型系统方面有两种选择——静态类型语言和动态类型语言。静态类型语言在编译过程中对数据类型整数、浮点数、双精度数、结构体和类以及这些类型之间的交互进行检查。动态类型语言则在运行时进行这些类型检查。静态类型语言的例子有C和Java动态类型语言的例子有Python、Perl和JavaScript。静态类型语言的一大优势在于由于所有类型检查都在编译时完成这使我们有机会在程序运行之前发现并消除许多错误。显然仅靠类型检查无法发现所有可能的错误但我们这里想强调的是静态类型语言在编译时查找与类型相关的错误和缺陷方面表现得明显更好。对于本质上高度依赖数值计算的低延迟应用程序来说尤其如此。静态类型语言的另一个巨大优势特别是对于低延迟应用程序而言是由于类型检查在编译时完成编译器有额外的机会在编译时优化类型和类型交互。实际上编译型语言速度快很多的一个重要原因就在于静态与动态类型检查系统的差异。这也是像Python这样的动态类型语言在创建数组和矩阵时像NumPy这样的高性能库需要指定类型的一个重要原因。多种编程范式与其他一些语言不同C并不强制开发者遵循特定的编程范式。它支持多种不同的编程范式如单体式、过程式、面向对象编程OOPObject-Oriented Programming、泛型编程等。这使得它适用于广泛的应用场景因为它赋予开发者灵活性让他们能够以实现最大优化和最低延迟的方式设计程序而不是将某种编程范式强加于应用程序。库C自带了庞大的C和C库为以下任务提供了大量的数据结构、算法和抽象网络编程动态内存管理数值运算错误和异常处理字符串操作常用算法输入/输出I/O操作包括文件操作多线程支持此外庞大的C开发者社区构建并开源了许多库在接下来的小节中我们将讨论一些最受欢迎的库。标准模板库标准模板库STLStandard Template Library是一个非常受欢迎且广泛使用的模板化头文件库包含数据结构、容器、这些容器的迭代器和分配器以及用于排序、搜索、容器算法等任务的算法。Boost库Boost是一个大型C库支持多线程、网络操作、图像处理、正则表达式regex、线性代数、单元测试等。Asio库Asio异步输入/输出Asynchronous Input/Output是另一个知名且广泛使用的库有两个版本非Boost版本和作为Boost库一部分的版本。它支持多线程并发用于实现和使用异步I/O模型并且可移植到所有主流平台。GNU科学库GNU科学库GSLGNU Scientific Library支持广泛的数学概念和运算如复数、矩阵和微积分并管理其他函数。活动模板库活动模板库ATLActive Template Library是一个模板密集型的C库用于帮助编写组件对象模型COMComponent Object Model程序。它取代了之前的Microsoft基础类库MFCMicrosoft Foundation Classes并对其进行了改进。它由微软开发是开源的并且大量使用了C一个重要的低延迟特性——奇异递归模板模式CRTPCuriously Recurring Template Pattern在本书中我们也将深入探讨并大量使用这一特性。它支持COM的多种特性如双重接口、ActiveX控件、连接点、分离接口、COM枚举器接口等。Eigen库Eigen是一个功能强大的用于数学和科学应用的C库。它包含线性代数函数、数值方法和求解器、复数等数值类型、几何相关的特性和操作等。LAPACK库线性代数包LAPACKLinear Algebra Package是另一个大型且极其强大的C库专门用于线性代数、线性方程以及支持大型矩阵的相关例程。它实现了许多功能如求解线性方程组、最小二乘法、特征值计算、奇异值分解SVDSingular Value Decomposition等。OpenCV库开源计算机视觉库OpenCVOpen Source Computer Vision是计算机图形和视觉相关应用中最知名的C库之一。它也有Java和Python版本提供了许多用于面部和物体识别、3D模型、机器学习、深度学习等的算法。mlpack库mlpack是一个超快的、仅包含头文件的C库适用于各种机器学习模型以及与之相关的数学运算。它还支持Go、Julia、R和Python等其他语言。QT库QT是目前用C构建跨平台图形程序时最受欢迎的库。它可在Windows、Linux、macOS甚至Android和嵌入式系统等平台上运行。它是开源的用于构建图形用户界面GUIGraphical User Interface小部件。Crypto库Crypto是一个免费的开源C库支持密码学相关的算法、操作和实用工具。它包含许多加密算法、随机数生成器、分组密码、函数、公钥操作、秘密共享等可在Linux、Windows、macOS、iOS和Android等多个平台上使用。适合大型项目在上一节中我们讨论了C的设计和众多特性这些使其非常适合低延迟应用程序开发。C的另一个特点是由于它为开发者提供了灵活性并允许构建各种高级抽象实际上它非常适合大型实际项目。出于这些原因像编译器、云处理和存储系统、操作系统这类大型项目都是用C编写的。我们将深入探讨这些以及许多其他试图在低延迟性能、丰富功能和不同业务场景之间取得平衡的应用程序通常情况下C是开发这类系统的完美选择。成熟且庞大的社区支持C编程语言最初创建于1972年随后C最初被称为“带类的C”于1983年诞生。C是一门非常成熟的语言广泛应用于许多不同业务领域的各种应用程序中。一些例子包括Unix操作系统、Oracle MySQL、Linux内核、Microsoft Office和Microsoft Visual Studio——这些都是用C编写的。C已经存在了40年这意味着大多数软件问题都已被遇到并且相应的解决方案也已被设计和实现。C也非常受欢迎是大多数计算机科学学位课程的一部分此外还有大量的开发者工具、第三方组件、开源项目、库、手册、教程、书籍等都围绕着它。关键是有大量的文档、示例和社区支持为新的C开发者和C项目提供帮助。持续积极发展的语言尽管C已有40年历史但它仍在持续积极发展。自1985年C第一个商业版本发布以来C标准和语言本身经历了多次改进和增强。按时间顺序已经发布了C 98、C 03、C 0X、C 11、C 14、C 17和C 20目前C 23正在开发中。每个版本都带来了改进和新特性。所以C是一门强大的语言并且随着时间不断发展持续增加现代特性。下面的图表展示了C多年来的发展历程图1.2 - C的发展历程鉴于C编程语言已经相当成熟具有超快的速度、高级抽象与底层硬件访问和控制的完美结合、庞大的知识库、开发者社区以及最佳实践、库和工具C显然是低延迟应用程序开发的首选语言。在本节中我们探讨了选择C编程语言进行低延迟应用程序开发的原因。我们讨论了它的各种特性、功能、库以及社区支持这些都使其非常适合这类应用程序。C深深融入到大多数对性能有严格要求的应用程序中也就不足为奇了。在下一节中我们将研究不同业务领域的许多不同低延迟应用程序目的是了解这些应用程序的共性。介绍一些重要的低延迟应用在本节中我们将探索不同业务领域的一些常见低延迟应用以便熟悉各类对延迟敏感的应用以及延迟在其性能中所起的重要作用。此外对这些应用的讨论将揭示它们在本质和设计上的一些相似之处。低级低延迟应用首先我们从那些被认为是极为低级的应用开始这意味着它们与硬件非常接近。请注意所有低延迟应用至少有一部分属于低级应用因为从定义上讲这是实现低延迟性能的方式。然而这些应用在整个程序中有很大一部分主要处理低级细节接下来我们就来讨论这些应用。电信我们已经讨论过C是速度最快的编程语言之一。它被广泛用于构建电话交换机、路由器、互联网设备、太空探测器以及电信基础设施的各种其他部分。这些应用需要处理大量的并发连接并促进它们之间的通信。这些应用需要快速且高效地执行这些任务这使它们成为低延迟应用的一个很好的例子。嵌入式系统与其他高级编程语言相比C更接近硬件因此它被用于对延迟敏感的嵌入式系统。这类系统的一些例子包括医疗领域使用的机器、手术工具、智能手表等等。C通常是诸如核磁共振成像MRI机器、实验室检测系统以及患者信息管理系统等医疗应用的首选语言。此外还有使用C对医疗数据进行建模、运行研究模拟等用例。编译器有趣的是各种编程语言的编译器都使用C和C来构建自身的编译器。原因同样是C和C属于低级语言更接近硬件能够高效地构建这些编译器。编译器应用本身能够在很大程度上优化编程语言的代码并生成低延迟的机器代码。操作系统从微软Windows到苹果macOS再到Linux本身所有主流操作系统都是用C构建的——这又是一个低延迟应用的例子C作为低级语言的特性使其成为理想之选。操作系统极其庞大且复杂。除此之外它们必须具备低延迟和高性能才能成为具有竞争力的现代操作系统。例如Linux通常是许多高负载服务器以及为低延迟应用设计的服务器的首选操作系统因此操作系统本身需要具备非常高的性能。除了传统操作系统C和C还被大量用于构建移动操作系统如iOS、安卓和Windows Phone的内核。总之操作系统需要在管理所有系统和硬件资源方面极其快速且高效。使用C开发操作系统的开发者可以利用该语言的特性构建超低延迟的操作系统。云/分布式系统开发和使用云及分布式存储与处理系统的机构对延迟的要求非常低。因此它们在很大程度上依赖于像C这样的编程语言。分布式存储系统必须支持非常快速和高效的文件系统操作所以需要接近硬件。此外分布式处理通常意味着高度的并发性依赖低延迟的多线程库以及高负载容忍度和可扩展性优化要求。数据库数据库是另一个需要低延迟、高并发和高并行性的应用示例。数据库也是许多不同业务领域中众多应用的关键组件。Postgres、MySQL和MongoDB目前是最受欢迎的数据库系统都是用C和C编写的——这再次证明了为什么C是低延迟应用的首选语言。C在设计和构建数据库以优化存储效率方面也非常理想。飞行软件和交通管制商用飞机和军用飞机的飞行软件属于对延迟要求极高的应用类别。在这里代码不仅要遵循非常严格的准则具备极高的稳健性并经过充分测试而且应用还需要可预测地在严格的延迟阈值内对事件做出响应和反应。交通管制软件依赖许多传感器这些传感器需要监测车辆的速度、位置和流量并将数据传输给中央软件。然后软件利用这些信息来控制交通标志、地图和交通信号灯。显然对于这样的实时应用需要具备低延迟特性并且能够快速高效地处理大量数据。高级低延迟应用在本小节中我们将讨论许多人可能认为的稍微高级一些的低延迟应用。这些是人们在尝试解决业务问题时通常会想到的应用然而需要记住的是这些应用仍然必须实施和使用低级优化技术以提供所需的性能。图形和视频游戏应用图形应用需要超快的渲染性能这使其成为低延迟应用的又一个例子。图形软件采用计算机视觉、图像处理等技术这通常涉及对大量大型矩阵进行许多快速且高效的矩阵运算。在视频游戏的图形渲染方面对低延迟性能的要求更为严格因为这些是交互式应用速度和响应性对用户体验至关重要。如今视频游戏通常会在多个平台上发布以覆盖更广泛的目标受众。这意味着这些应用或其精简版本需要在低端设备上运行而这些设备可能没有太多的计算和内存资源。总体而言视频游戏包含许多资源密集型操作如渲染图形、同时处理多个玩家、快速响应用户输入等等。C非常适合所有这些应用并且已被用于创建许多知名游戏如《反恐精英》《星际争霸》和《魔兽争霸》以及游戏引擎如虚幻引擎Unreal Engine。C也很适合不同的游戏平台如Windows个人电脑、任天堂Switch、Xbox和PlayStation。增强现实和虚拟现实应用增强现实ARAugmented Reality和虚拟现实VRVirtual Reality都是对现实生活环境进行增强或创建全新虚拟环境的技术。AR通过在我们的实时视野中添加数字元素来增强环境而VR则创建一个全新的模拟环境。因此这些应用将图形渲染和视频游戏应用提升到了一个全新的水平。AR和VR技术在许多不同的业务场景中都有应用如设计与施工、维护与修理、培训与教育、医疗保健、零售与营销甚至在技术领域本身。AR和VR应用与视频游戏应用有相似的要求需要实时处理来自各种来源的大量数据同时无缝流畅地处理用户交互。这些应用面临的技术挑战包括处理有限的处理能力和可用内存、可能有限的移动带宽以及保持低延迟和实时性能以不影响用户体验。浏览器网络浏览器往往比它们看起来复杂得多。浏览器中有渲染引擎对低延迟和高效处理有着较高要求。此外浏览器还经常与数据库交互并包含交互式渲染代码这样用户就无需长时间等待内容更新或交互式内容的响应。鉴于浏览器对低延迟的要求C成为这类应用的首选语言也就不足为奇了。事实上一些最受欢迎的网络浏览器如谷歌Chrome、Mozilla Firefox、Safari、Opera等都大量使用了C。搜索引擎搜索引擎是另一个对低延迟以及高效的数据结构、算法和代码库有要求的应用场景。像谷歌这样的现代搜索引擎会运用互联网爬虫技术、索引基础设施、网页排名算法以及包括机器学习在内的其他复杂算法。谷歌的搜索引擎依靠C以极低延迟和高效的方式满足所有这些需求。库许多高级库通常有严格的性能要求其本身就可被视为低延迟应用而且它们往往是更大的低延迟应用和业务中的关键组件。这些库涵盖不同领域包括网络编程、数据结构、更快速的算法、数据库、多线程、数学库例如机器学习相关的库等等。这类库需要极低的延迟和高性能的处理比如涉及大量矩阵运算的计算其中许多矩阵的规模也可能非常大。显然在这类应用中性能至关重要这也是C经常被大量使用的另一个领域。尽管像TensorFlow这样的许多库在Python中都能使用但实际上其核心的机器学习数学运算在底层是用C实现的以此来支持在海量数据集上的机器学习方法。银行和金融应用银行应用是另一类低延迟应用每天需要处理数百万笔交易要求低延迟、高并发和高可靠性。大型银行拥有数百万客户和数亿笔交易所有这些交易都需要准确、快速地执行并且能够扩展以应对客户负载进而处理数据库和服务器的负载。基于前面讨论的原因C自然成为许多这类银行应用的选择。在金融建模、电子交易系统和交易策略等应用中低延迟比其他任何领域都更为关键。C的速度和可确定性的性能使其成为处理数十亿市场更新、发送数百万笔订单以及在交易所进行交易的理想选择尤其是在高频交易HFT方面。由于市场变化非常迅速交易应用需要快速获取准确的数据以极快的速度执行交易。系统中的高延迟可能会导致损失严重影响交易利润甚至更糟。在研发方面对多个交易所的众多交易工具进行模拟也需要大规模的低延迟分布式处理以便快速、高效地完成。定量开发、研究和风险分析库也用C编写因为它们需要尽可能快地处理大量数据。其中一个很好的例子是定价和风险库它们计算期权产品的公平交易价格并通过运行大量模拟来评估期权风险因为其搜索空间非常庞大。手机应用现代手机应用功能丰富。此外它们还必须在硬件资源非常有限的平台上运行。这就使得这些应用的实现需要极低的延迟并且在使用有限资源时要做到高效这一点变得更加重要。然而这些应用仍需对用户交互做出极快的响应可能还需要处理后端连接并在移动设备上渲染高质量的图形。像安卓Android和Windows操作系统这样的移动平台、谷歌Chrome和Firefox这样的浏览器以及YouTube这样的应用都大量使用了C。物联网和机器对机器应用物联网Internet of ThingsIoT和机器对机器machine-to-machineM2M应用基于设备之间的连接实现自动收集、存储和交换数据。总体而言虽然物联网和机器对机器在本质上相似但在网络、可扩展性、互操作性以及人机交互等方面存在一些差异。物联网是一个宽泛的术语指的是将不同的物理设备连接在一起。物联网设备通常是嵌入在其他大型设备中的执行器和传感器如智能恒温器、冰箱、门铃、汽车、智能手表、电视和医疗设备。这些设备在计算资源、电力需求和可用内存资源都有限的平台上运行。机器对机器是一种通信方式多台机器在无需人工监督或交互的情况下通过有线或无线连接相互交互。这里的关键是机器对机器通信不一定需要互联网连接。所以物联网是机器对机器的一个子集而机器对机器是一个更广泛的基于机器对机器通信的系统范畴。机器对机器技术应用于不同领域如安全、跟踪、自动化、制造和设施管理。我们之前已经讨论过这些应用在此再总结一下物联网和机器对机器技术应用于电信、医疗保健、制药、汽车和航空航天工业、零售和物流以及供应链管理、制造业和军事卫星数据分析系统等领域。本节介绍了低延迟应用蓬勃发展的不同业务领域和应用场景在某些情况下低延迟应用对相关业务来说是必不可少的。我们希望你能理解低延迟应用在许多不同领域都有应用尽管这可能并不那么显而易见。此外我们还想说明即使这些应用旨在解决不同的业务问题但它们有很多相似之处。总结在本章中我们介绍了低延迟应用。首先我们定义了对延迟敏感和对延迟关键的应用以及不同的延迟度量方式。然后讨论了在低延迟应用中重要的不同指标以及其他确定低延迟应用需求的考虑因素。在本章的一个部分我们探讨了为什么C在不同业务领域的低延迟应用中最常被选用。具体来说我们讨论了C语言本身的特性以及该语言的灵活性和底层特性这些使得C非常适合低延迟应用。最后我们研究了不同业务领域中许多低延迟应用的示例以及它们的共同之处。讨论这些的目的在于尽管业务场景不同但这些应用有很多共同的需求和特点。同样C适合即便不是全部也适合大多数不同业务领域的这些低延迟应用。在下一章中我们将更详细地讨论一些最受欢迎的低延迟应用。在本书中我们将以低延迟电子交易为例来理解和应用C低延迟技术。不过在此之前我们还将探索其他低延迟应用如实况视频流、实时离线和在线视频游戏应用以及物联网应用等。