什么是延迟、吞吐量和并发程度?


chrisapotek问道。 您如何定义测试的吞吐量和延迟?

没有简单的问题,所以我用帖子回复了。

持续吞吐量

 

我认为吞吐量是指一个进程在一段持续的时间内(10秒到一天之间)可以执行的操作数。(假设你有一个相当长的时间来补上)我把它测量为每秒的动作数或者每秒兆字节数,但是我觉得测试需要运行超过一秒钟才能稳定。较短的测试仍然可以报告每秒的吞吐量,但这是不现实的,因为系统被设计为使用缓存和缓冲区来处理突发的活动。

如果你单独测试一个行为,你会得到一个数字,这个数字假设系统上没有其他东西在运行,这些缓冲区的限制并不重要。当你在一台真正的机器上运行一个真正的应用程序做其他事情时,它们将不能充分利用缓存、缓冲区、内存和带宽,你可能无法获得2-3倍的持续吞吐量,更不用说更乐观的突发吞吐量了。SATA硬盘可以报告500兆字节/秒的突发吞吐量,但它可能只能达到40兆字节/秒。当运行一个真实的程序时,您可能希望得到15-25兆字节/秒。

潜伏

有两种方法可以报告延迟。单向延迟和往返延迟(或往返时间)。第一种经常被报道,因为它比较少,但是很难精确测量,因为你需要一个两端同步的时钟。出于这个原因,您经常测量往返延迟(因为您可以只使用一个精确的时钟),并可能将其减半以推断单向延迟。我倾向于对真实应用程序的期望感兴趣,而更高的往返延迟通常是更好的指示。

延迟的一个常见度量是取吞吐量的倒数。虽然这更容易计算,但它只能与以这种方式测量的其他测试相比,因为它只能让您对延迟有最乐观的看法。例如,如果您在环回时通过TCP异步发送消息,您可能每秒能够发送200万条消息,并且您可能推断每个消息的延迟大约是500 ns。如果你在每条信息上打上时间标记,你会发现发送和接收之间的典型时间实际上接近20微秒。你能从这个差异中推断出什么?任何时候都有大约40条(20 us / 500 ns)的消息在飞行。

典型、平均和百分位数延迟

典型延迟可以通过计算单个延迟、对它们进行排序并取中间值来计算。这可能是一个相当乐观的值,但是因为它是最低的,所以它可能是你想要报告的值。平均延迟是延迟的总和除以计数。这经常被报道,因为这是最简单的计算和理解它的意思。因为它考虑了所有的值,所以比典型的延迟更现实。更保守的观点是报告90%、99%、99.9%甚至99.99%的潜伏期。这是通过对单个延迟进行排序并取最高的10%、1%、0.1%或0.01%来计算的。因为这代表了你大部分时间的等待时间,所以这是一个更好的数据。典型的延迟实际上是50%。

比较典型延迟和平均延迟以了解分布有多“平坦”是很有用的。如果典型和平均延迟在10%以内,我认为这是相当平坦的。必须高于此值表示有机会优化您的绩效。在性能良好的系统中,我希望90%、99%和99.9%之间的延迟是原来的两倍。潜伏期的分布通常有所谓的“肥尾巴”。偶尔你会有比所有其他值都大得多的值。这些可能会高出10-1000倍。这是什么看平均或百分位延迟更重要,因为这是一个会给你带来麻烦。典型延迟对于确定系统是否可以优化更有用。

报告这些延迟和吞吐量的测试

测试”How much difference can thread affinity make“就是我所说的回声或ping测试。一个线程或进程发送包含时间戳的短消息。该服务接收消息并将其发回。原始发送方读取消息,并将消息中的时间戳与读取消息时所用的另一个时间戳进行比较。不同之处在于以毫微秒(或我做的一些测试中的微秒)为单位测量的延迟

更少的延迟不会带来更高的吞吐量吗?你能用凡人的语言来解释这个概念吗?
有许多技术可以提高延迟和吞吐量。例如使用更快的硬件,优化代码以使其更快。然而,有些技术只能提高吞吐量或延迟。例如,使用缓冲、批处理或异步通信(在NIO2中)提高了吞吐量,但代价是延迟。相反,使代码尽可能简单并减少跳数往往会减少延迟,但可能不会带来高吞吐量。例如,一次发送一个字节,而不是使用缓冲流。每个字节都可以以较低的延迟接收,但吞吐量会受到影响。

你能用凡人的语言来解释这个概念吗?
简单来说,延迟是每个动作的时间,吞吐量是每次动作的数量。我使用的另一个概念是数量“飞行中”或“并发程度”,即并发=吞吐量*延迟

并发程度示例

如果任务花费1毫秒,吞吐量为每秒1000,则并发度为1 (1/1000 * 1000)。换句话说,任务是单线程的。
如果一项任务需要20微秒,吞吐量为每秒200万条消息,“飞行中”的数字是40 (2e6 * 20e-6)
如果硬盘的延迟为8毫秒,但可以写入40兆字节/秒,则每次寻道写入的数据量约为320千字节(40e6字节/秒* 8e-3秒= 3.2e5字节)