# F.11 谬误与陷阱
<!-- source: p1065 -->

互连网络领域流传着不少误解，也有许多容易忽略的风险。本节给出若干提醒，设计时应谨慎。

## 谬误：互连网络已经很快，无须改进

互连网络与存储器、I/O 子系统一样，为系统提供特定功能。设计目标应是让处理器尽可能快地执行指令，因此其带宽必须足够高，避免持续饱和而成为整体瓶颈。

20 世纪 80 年代引入虫孔交换后，用单芯片交换机构建大直径拓扑成为可能，网络带宽容量不再一定是限制因素。这却使人错误地认为互连无须继续改进。自那时以来，人们大量关注处理器性能，对互连的关注相对少得多。随着技术进步，互连在系统资源、成本、功耗，以及其他影响功能和性能的属性中所占比例越来越大。单纯把某些网络参数做得过大以提高带宽，已不再具备成本可行性。设计者必须将端到端互连与处理器、存储器和 I/O 子系统协同设计，满足整个系统的成本、功率、功能和性能目标。带片上网络的多核处理器就是显例。

## 谬误：二分带宽是网络的准确成本约束

二分带宽虽然很流行，却从未成为实际互连实现的主要约束，尽管未来可能如此。相比成本指标，它更适合做性能指标。芯片引脚数才是更实际的带宽约束。

## 陷阱：只用带宽，尤其二分带宽，衡量网络性能

网络总带宽或二分带宽很少是端到端真正的瓶颈。即使是，分组穿越二分面的效率几乎从不为 100%，即 \(\rho<100\%\)；网络端点接收效率也几乎不为 100%，即 \(\sigma<100\%\)。前者高度依赖路由、交换、仲裁等因素，两者又都高度依赖流量特征。忽略这些因素，<!-- source: p1066 -->只看原始带宽，会严重误判性能。例如，一个网络的总带宽或二分带宽完全可能更高，测量性能却更低。

TCP/IP 等复杂协议能够尽量提高交付带宽，这似乎使不少网络公司相信网络只有一个评价指标。对视频流这类收发双方少有交互的应用，也许如此；但许多应用是请求—响应型，每条大消息都伴随一条或多条小消息，NFS 就是一例。

图 F.41 比较 NFS 流量在共享 10 Mbit/s 以太网 LAN 与交换式 155 Mbit/s ATM LAN 上的表现。以太网驱动优化更好，因此载荷不超过 512 字节时，10 Mbit/s 以太网反而更快。表中分别给出发送全部 NFS 消息的开销、传输及总时间。ATM 峰值链路速度高约 15 倍，8 KB 消息的实测链路速度也近九倍，但较高开销抵消了带宽优势，发送 NFS 流量最终只快 1.2 倍。

<!-- source: p1067 -->

| 大小，字节 | 消息数 | ATM 开销，秒 | 以太网开销，秒 | 数据字节数 | ATM 传输，秒 | 以太网传输，秒 | ATM 总时间，秒 | 以太网总时间，秒 |
|---:|---:|---:|---:|---:|---:|---:|---:|---:|
| 32 | 771,060 | 532 | 389 | 33,817,052 | 4 | 48 | 536 | 436 |
| 64 | 56,923 | 39 | 29 | 4,101,088 | 0 | 5 | 40 | 34 |
| 96 | 4,082,014 | 2817 | 2057 | 428,346,316 | 46 | 475 | 2863 | 2532 |
| 128 | 5,574,092 | 3846 | 2809 | 779,600,736 | 83 | 822 | 3929 | 3631 |
| 160 | 328,439 | 227 | 166 | 54,860,484 | 6 | 56 | 232 | 222 |
| 192 | 16,313 | 11 | 8 | 3,316,416 | 0 | 3 | 12 | 12 |
| 224 | 4820 | 3 | 2 | 1,135,380 | 0 | 1 | 3 | 4 |
| 256 | 24,766 | 17 | 12 | 9,150,720 | 1 | 9 | 18 | 21 |
| 512 | 32,159 | 22 | 16 | 25,494,920 | 3 | 23 | 25 | 40 |
| 1024 | 69,834 | 48 | 35 | 70,578,564 | 8 | 72 | 56 | 108 |
| 1536 | 8842 | 6 | 4 | 15,762,180 | 2 | 14 | 8 | 19 |
| 2048 | 9170 | 6 | 5 | 20,621,760 | 2 | 19 | 8 | 23 |
| 2560 | 20,206 | 14 | 10 | 56,319,740 | 6 | 51 | 20 | 61 |
| 3072 | 13,549 | 9 | 7 | 43,184,992 | 4 | 39 | 14 | 46 |
| 3584 | 4200 | 3 | 2 | 16,152,228 | 2 | 14 | 5 | 17 |
| 4096 | 67,808 | 47 | 34 | 285,606,596 | 29 | 255 | 76 | 290 |
| 5120 | 6143 | 4 | 3 | 35,434,680 | 4 | 32 | 8 | 35 |
| 6144 | 5858 | 4 | 3 | 37,934,684 | 4 | 34 | 8 | 37 |
| 7168 | 4140 | 3 | 2 | 31,769,300 | 3 | 28 | 6 | 30 |
| 8192 | 287,577 | 198 | 145 | 2,390,688,480 | 245 | 2132 | 444 | 2277 |
| **合计** | **11,387,913** | **7858** | **5740** | **4,352,876,316** | **452** | **4132** | **8310** | **9872** |
{#fig-F.41 .wide .expand num="F.41" caption="10 Mbit/s 以太网与 155 Mbit/s ATM 的总时间，分别计算总开销和传输时间。计算传输时间时，须把头部大小加到数据字节数中。ATM 软件驱动较高的开销抵消了其网络带宽优势。测量于 1994 年进行，使用 SPARCstation 10、Fore Systems SBA-200 ATM 接口卡及 ASX-200 交换机。NFS 数据由加利福尼亚大学伯克利分校 Mike Dahlin 测量。"}

> **译注：**表内个别行显示的分项之和与显示的总时间不一致。

<!-- source: p1066 -->

## 陷阱：接收链路带宽不足，使端节点更成为性能瓶颈

除非流量模式是一一置换，否则多数源同时注入流量时，一些目的地会同时收到多个分组，从而争用。如果不处理，争用可能演变为拥塞，并传播到整个网络。可通过分析流量模式、提供额外接收带宽应对，例如让接收带宽高于注入带宽。IBM Blue Gene/L 的片上交换机就采用 7 位注入链路、12 位接收链路，接收带宽等于交换机全部输入链路总带宽。

## 陷阱：使用高性能 NIC，却忘记 NIC 与主机处理器之间的 I/O 子系统

这与上一个问题有关。消息通常先在用户空间缓冲区中组成，再调用通信库发送函数；某些 SAN 和 OCN 也可能由实现一致性协议的 缓存 控制器组成消息。两种情况下，传输前都必须将消息复制到网络接口存储器。如果 I/O 带宽低于链路带宽，或引入较大开销，通信性能会明显受影响。例如，最早上市的万兆以太网卡使用 PCI-X 系统总线接口，其带宽显著低于 10 Gbit/s。

<!-- source: p1067 -->

## 谬误：零复制协议无须在缓冲区之间复制消息或片段

传统计算机网络协议只允许通过特权模式系统调用访问通信设备。因此，发送消息时，通信例程需要将用户缓冲区内容复制到内核缓冲区。协议可能需要保留副本，以便出错重传，而系统调用一旦返回应用，应用就可能修改<!-- source: p1068 -->用户缓冲区。零复制协议的通信例程在用户空间执行，协议也简单得多，因此消除了这一缓冲区到缓冲区的复制。

不过，消息仍须从应用缓冲区复制到 NIC 存储器，网卡硬件才能从那里向网络发送。直接在 NIC 内存分配应用消息缓冲，可以消除这一复制，某些协议确实如此；但这在当时系统中未必方便，因为 NIC 内存通常通过 I/O 子系统访问，远慢于主存。一般更高效的办法，是在主存组成消息，再让 DMA 设备搬到 NIC 内存。

还有一份很少被计入的复制：从计算消息片段的地方，通常为 ALU，结果先在处理器寄存器中，复制到主存。20 世纪 80 年代的某些类脉动体系结构，如 iWarp，能把消息片段从处理器直接送入网络，真正消除全部消息复制。Cray X1E 共享内存多处理器超级计算机也采用这一方法。

接收端同样有类似问题。不过，这并不意味着零复制协议低效；它们代表当时系统使用的最高效实现类型。

## 陷阱：评估性能时忽略软件开销

要降低软件开销，必须得到操作系统和通信库配合。即使协议卸载，软件开销仍大于硬件开销，绝不能忽略。图 F.32 和 F.41 分别展示 SAN 与 WAN 标准的实例，超级计算机专有 SAN 也有类似情况。20 世纪 90 年代初，Connection Machine CM-5 发送消息的软件开销为 20 μs，硬件仅 0.5 μs。同一时期第一代 Intel Paragon 的硬件开销只有 0.2 μs，初版软件却有 250 μs；后续降至 25 μs，再降到几微秒，仍然主导硬件开销。IBM Blue Gene/L 的 MPI 发送／接收开销约为 3 μs，其中硬件最多只占三分之一。

这不过是 Amdahl 定律在网络中的体现：若软件开销没有同步降低，更快的网络硬件就难以发挥作用。如今 OS bypass、轻量协议和卸载已将软件开销通常降到几微秒甚至更少，但它仍是重要性能因素。

## 谬误：MIN 比直接网络更具成本效益

MIN 所用交换机通常明显少于待连接设备数。直接网络则往往在每节点内集成交换机，交换机数与<!-- source: p1069 -->节点数相同。但完全可以在一个节点放多个计算设备，例如片上有交换机的多核处理器，或让多个设备连接一台交换机，即 bristling。此时，直接网络的成本效益可以与 MIN 相当甚至更好。注意，MIN 每个节点还可能需要多块网络接口，才能匹配直接网络每节点多条链路的带宽。

## 谬误：低维直接网络比超立方体等高维网络性能更高

一些研究以二分带宽为主要物理约束，分析最优维数后得出这一结论。但多数研究没有考虑链路流水化，只考虑很短的链路，或忽略交换机体系结构约束。把二分带宽当作主要限制，也使结论失准。如今多数研究者和设计者，包括此前得出相反结论的一部分人，都认为高 radix，即高端口数，交换机比低 radix 更具成本效益。

## 谬误：虫孔交换比其他交换技术性能更好

虫孔交换与虚拟 cut-through 等流水交换技术的空载延迟相同。20 世纪 80 年代末虫孔交换机出现，恰逢网络带宽大幅增长，许多人便认为性能提升主要来自虫孔交换。实际上，主要收益来自链路带宽急剧提高；而链路带宽提高，是因为虫孔允许用片上缓冲存分组片段，不必使用节点主存或其他片外存储。后来更大的片上缓冲成为可能，虚拟 cut-through 在达到相同空载延迟的同时，提供高得多的吞吐量。但虫孔交换并未因此消失；在只能采用小缓冲的应用中，例如某些 OCN，它仍是首选。

## 谬误：少量虚拟通道总能让分组越过前方阻塞分组，从而提高吞吐量

一般而言，在虫孔交换机中采用少量虚拟通道是好主意，分组较可能越过前方阻塞分组，降低延迟、显著提高吞吐量。但虚拟 cut-through 的收益没那么大。它的缓冲区应足以容纳多个分组，因此每个虚拟通道都可能引入 HOL 阻塞，高负载下甚至降低性能。增加虚拟通道提高成本，<!-- source: p1070 -->却可能收效甚微，除非通道数与交换机端口数相同，并按目的地映射分组，即使用虚拟输出排队。

虚拟通道当然可以分离不同流量类别，在虚拟 cut-through 网络中很有价值。但按 flit 在物理链路上复用，会让不同虚拟通道的所有分组都受到延迟。若按整分组复用，平均延迟会明显更低；此时又必须限制分组大小，避免一个分组独占大部分链路带宽。

## 谬误：自适应路由导致乱序，目的端重新排序开销太大

自适应路由让分组根据流量选择不同路径，因此通常会导致乱序交付。但这不必然意味着目的端重排开销很大，以至自适应路由没有价值。例如，迄今最高效的一些算法在部分虚拟通道支持完全自适应路由，同时要求其他通道采用确定性路由避免死锁，IBM Blue Gene/L 就是这样。此时，每个分组都很容易在两者间选择：头部一个比特即可告知交换机，是可用全部虚拟通道，还是只用确定性通道。配合如下协议，就能消除目的端重排开销。

并行计算机和集群的多数通信协议，会按消息大小使用两种机制。短消息采用 **eager 协议**，直接发送，接收节点用预分配缓冲暂存。长消息采用 **rendezvous 协议**：先发送控制消息，请求目的端分配足以容纳整条消息的缓冲区；目的端确认分配后，发送者将消息拆成有大小上限的分组并传送。

若 eager 消息只用确定性路由，显然没有重排开销。长消息的分组则可自适应路由，每个分组都含消息内序号或距消息起点的偏移量，因此目的节点能直接放入消息缓冲中的正确位置，相比确定性路由没有额外复制或重排。唯一差别是完成条件：不再只检查消息最后一个分组是否<!-- source: p1071 -->到达，而要累计到达分组，计数与消息大小相符时通知接收完成。长消息即使不频繁，通常也占大部分带宽，所以多数分组都能从自适应路由获益，而无须增加重排开销。

## 谬误：自适应路由提供备选路径，因此本身总能提高容错能力

仅有自适应路由不足以容忍链路或交换机故障。还需要检测并通知故障的机制，路由逻辑才能排除故障路径、使用剩余路径。而且，同一故障在确定性路由下只影响一定数量的路径，自适应路由下却可能影响更多源—目的节点对。因此，某些自适应交换机在故障时会切换到确定性路由，由源节点选择备选路径。

例如 Cray T3E 用**方向顺序路由**容忍少量故障，按方向次序使用资源，如 \(X^+\)、\(Y^+\)、\(Z^+\)、\(Z^-\)、\(Y^-\)、最后 \(X^-\)，避免形成环。同时，需要时很容易经非最短路径绕过故障部件；例如，即使分组稍后必须向 \(X^-\) 移动，也可先沿 \(X^+\) 走几跳。

## 陷阱：只在网络内部实现功能，而不做端到端实现

问题在于，把只能在最高层完成的功能放到较低层，便只能部分满足通信需求。Saltzer、Reed 和 Clark［1984，第 278 页］提出**端到端论证**：

> 只有了解通信系统两端的应用，并得到应用协助，才能完整、正确地规定所讨论的功能。因此，不可能仅把该功能作为通信系统自身的一项特性来完整提供。

他们举了 MIT 一个网络的例子：网络有多个网关，每个都为到下一网关的传输添加校验和。应用程序员误以为校验和保证了准确性，认为消息存于各网关内存期间也受保护。后来一个网关出现瞬态故障，每传输一百万字节就交换一对字节。久而久之，一套操作系统的源代码反复经过该网关，被逐渐破坏。唯一办法竟是将受损文件与纸质程序清单对照，手工修复！如果校验和由端系统应用计算和<!-- source: p1072 -->检查，就能保证安全。

不过，只要有端到端检查，链路级中间检查仍有价值。端到端检查只能发现两节点之间某处出错，不能定位；中间检查可以找出坏掉的部件。

第二个问题是性能。出错时由端点重传整个消息，虽足以保证正确性，但在中间位置只重传消息的一部分，往往比等待端点超时再全部重传快得多。

## 陷阱：不顾延迟、带宽或软件要求，所有网络一律使用 TCP/IP

早期工作站网络设计者认为，不管消息是发到房间另一头还是大洋彼岸，都采用同一协议栈很优雅，于是都必须付出 TCP/IP 开销。考虑到早期以太网硬件不可靠，这当时也许明智，却为后来的商用系统设下高软件开销门槛。如果消息只走几十米甚至更短，软件却浪费数百微秒，那么低延迟接口硬件和互连就很难获得投入动力。TCP/IP 还会占用大量处理器资源。一个粗略经验是，每 1 Mbit/s 带宽需要约 1 MHz 处理器速度，因此 1000 Mbit/s 链路可能使一颗 800–1000 MHz 处理器饱和。

反过来看，从软件角度 TCP/IP 最有吸引力，因为连接面最广，带来的机会最多。针对某种 LAN 或 SAN 优化的软件，适用范围有限。例如 Java 程序通信依赖 TCP/IP，若为另一协议优化，就必须编写连接 Java 与该协议的适配软件。

TCP/IP 支持者指出，协议本身理论上不必像当时实现那么沉重，但商用系统的进步有限。市场已有 TCP/IP 卸载引擎，希望既保持通用软件模型，又降低处理器占用和消息延迟。如果处理器性能继续远快于网络速度增长，或者多处理器变得普遍，软件 TCP/IP 对处理器占用和消息延迟的影响也可能减弱。
