计算吞吐量的正确方法是什么?
有多种方法,具体取决于您要测量的具体内容。正如您所提到的,它们都归结为将一定数量的位(或字节)划分为一定的持续时间;不同的是您正在计算哪些位,或者(更罕见的是)您正在考虑哪些时间来测量持续时间。
您需要考虑的因素有:
您在网络堆栈的哪一层测量吞吐量?
如果您在应用层进行测量,那么重要的是您将哪些有用数据传输到另一个端点。例如,如果您正在传输 6 kB 的文件,则在测量吞吐量时计算的数据量为 6 kB(即 6,000 字节,而不是位,并注意乘数 1000,而不是 1024;这些约定在网络中很常见)。
这通常称为goodput,它可能与在传输层(如在 TCP 或 UDP 中)实际发送的内容不同,原因有两个:
1。标题导致的开销
网络中的每一层都会为数据添加一个标头,由于其传输时间,这会引入一些开销。此外,传输层将您的数据分成段;这是因为网络层(如在 IPv4 或 IPv6 中)具有称为 MTU 的最大数据包大小,在以太网中通常为 1,500 B。该值包括网络层标头大小(例如 IPv4 标头,其长度可变,但通常为 20 B 长)和传输层标头(对于 TCP,它的长度也是可变的,但通常为 40 B 长)。这导致最大段大小MSS(一个段中的数据字节数,没有标头)为 1500 - 40 - 20 = 1440 字节。
因此,如果我们要发送 6 kB 的应用层数据,我们必须将其分成 6 段,每段 1440 字节中的 4 段和 240 字节中的段。然而,在网络层,我们最终发送了 6 个数据包,每个 1500 字节中的 4 个和 300 字节中的一个,总共 6.3 kB。
这里我没有考虑链接层(如Ethernet)添加自己的标题和可能还有后缀的事实,这进一步增加了开销。对于以太网,以太网报头有 14 个字节,VLAN 标记可选 4 个字节,然后是 4 个字节的 CRC 和 12 个字节的间隙,每个数据包总共 36 个字节。
如果您考虑固定速率的链路,例如 10 Mb/s,根据您的测量,您将获得不同的吞吐量。通常你需要以下之一:
- goodput,即应用层吞吐量,如果您要衡量的是应用程序性能。在此示例中,您将 6 kB 除以传输持续时间。
- 链路层吞吐量,如果您要测量的是网络性能。对于此示例,您将 6 kB + TCP 开销 + IP 开销 + 以太网开销 = 6.3 kB + 5 * 36 B = 6516 B 除以传输持续时间。
重传开销
Internet 是一个尽力而为的网络,这意味着数据包将在可能的情况下被传递,但也可能被丢弃。在 TCP 的情况下,数据包丢失由传输层纠正;对于 UDP,没有这样的机制,这意味着要么应用程序不关心数据的某些部分是否没有被传递,要么应用程序在 UDP 之上实现自己的重传。
重传减少goodput有两个原因:
一个。有些数据需要再次发送,这需要时间。这引入了一个延迟,该延迟与发送方和接收方之间网络中最慢链路的速率(也称为瓶颈链路)的速率成反比。
湾。检测到某些数据未传递需要从接收方反馈给发送方。由于传播延迟(有时称为延迟;由电缆中的有限光速引起),反馈只能由发送方接收到一些延迟,这会进一步减慢传输速度。在大多数实际情况下,这是对重传造成的额外延迟的最重要贡献。
显然,如果您使用 UDP 而不是 TCP,并且您不关心丢包,您当然会获得更好的性能。但是对于很多应用来说,数据丢失是不能容忍的,所以这样的测量是没有意义的。
有些应用程序确实使用 UDP 传输数据。一个是 BitTorrent,它可以使用 TCP 或他们设计的称为uTP 的协议,它在 UDP 之上模拟 TCP,但旨在通过许多并行连接更高效。另一个通过 UDP 实现的传输协议是 QUIC,它也模拟 TCP,并通过单个连接提供多路复用多个并行传输,并通过前向纠错来减少重传。
我将稍微讨论前向纠错,因为它与您关于吞吐量的问题有关。实现它的一种简单方法是发送每个数据包两次。万一丢失了,另一个仍然有机会被接收。这将重传的数量减少到一半,但由于您发送了冗余数据(请注意,网络或链路层的吞吐量保持不变!),因此您的吞吐量也会减半。在某些情况下,这很好;尤其是在延迟非常大的情况下,例如在洲际或卫星链路上。此外,存在一些数学方法,您不必发送数据的完整副本。例如,对于您发送的每 n 个数据包,您会发送另一个冗余数据包,即它们的 XOR(或其他一些算术运算);如果多余的丢失了,没关系;如果 n 个数据包中的一个丢失,您可以根据冗余的一个和另一个 n-1 来重建它。因此,您可以将前向纠错引入的开销配置为您可以节省的任何带宽量。
你是如何测量传输时间的
当发送方完成通过线路发送最后一个比特时,传输是否完成,或者它是否还包括最后一个比特传输到接收方所需的时间?另外,是否包括从接收方得到确认,说明所有数据已成功接收,无需重传的时间?
这实际上取决于您要测量的内容。请注意,对于大额传输,在大多数情况下,额外的一个round-trip-time 是微不足道的(除非您正在与火星上的探测器进行通信)。
TCP 的哪个关键特性使其具有比 UDP 高得多的吞吐量?
这不是真的,尽管这是一个常见的误解。
除了在需要时重传数据外,TCP 还会调整其发送速率,使其不会因拥塞网络而导致丢包。调整算法经过数十年的完善,通常很快收敛到网络支持的最大速率(实际上是瓶颈环节)。由于这个原因,在吞吐量上通常很难超过 TCP。
使用 UDP,发送方没有速率限制。 UDP 允许应用程序发送尽可能多的数据。但是,如果您尝试发送的数据超出网络的处理能力,则会丢失一些数据,从而降低您的吞吐量,并且还会让您正在拥塞的网络管理员非常生气。这意味着以高速率发送 UDP 流量是不切实际的(除非目标是 DoS 网络)。
一些media applications 正在使用UDP,但以非常小的速率限制发送方的传输。这通常用于 VoIP 应用程序或 Internet Radio,在这些应用程序中您需要很少的吞吐量但延迟很低。我想这是造成 UDP 比 TCP 慢的误解的原因之一;事实并非如此,UDP 可以与网络允许的一样快。
正如我之前所说,有一些协议,例如 uTP 或 QUIC,通过 UDP 实现,其性能类似于 TCP。
这是真的吗?
TCP throughput = (TCP Window Size / RTT)
没有丢包(和重传),这是正确的。
TCP throughput = BDP / RTT = (Link Speed in Bytes/sec * RTT)/RTT = Link Speed in Bytes/sec
仅当窗口大小配置为最佳值时,这才是正确的。 BDP/RTT 是网络中的最佳(最大可能)传输速率。大多数现代操作系统应该能够以最佳方式自动配置它。
吞吐量如何取决于块大小?块大小等于 TCP 窗口还是 UDP 数据报大小?
我在iperf documentation 中看不到任何块大小。
如果您参考 TCP 窗口大小,如果它小于 BDP,那么您的吞吐量将不是最佳的(因为您浪费时间等待 ACK 而不是发送更多数据;如果需要我可以进一步解释)。如果它等于或高于 BDP,那么您将获得最佳吞吐量。