计算机体系结构中的网络:从DMA到DPU的硬件/软件协同

📅 发布时间:2026/10/2 9:03:19
计算机体系结构中的网络:从DMA到DPU的硬件/软件协同
提到“计算机体系结构”大多数人的第一反应是CPU流水线、缓存一致性、存储层次这些硬核内容。等到教材翻到第七章“网络”时很多人心里其实会犯嘀咕网络不是《计算机网络》课该讲的东西吗体系结构掺和进来算怎么回事我最初也这么想。直到真正把这章反复读透、又在一线处理过几年网络性能问题之后才意识到体系结构视角下的网络和纯网络工程视角完全不是一回事。这一章不教你配置交换机也不让你背报文格式它真正要回答的是当一个网络数据包到达网卡之后一路穿过协议栈、DMA、内存、Cache最后被应用程序拿到这个过程里计算机系统做了什么又是什么在决定它的快慢。1. 先搞清楚体系结构视角下的“网络”到底在讲什么1.1 教材这章不是计算机网络课它的主线是“系统怎么走到一起”我见过不少人把这章当成TCP/IP的浓缩版去学结果越看越糊涂。原因很简单《计算机体系结构》里的网络章节从标题到内容都不是在讲“网络上跑什么协议”而是在讲“计算节点之间怎么高效互连”。注意“互连”这个词。单机时代CPU、内存、I/O设备通过总线或片上网络连在一起这属于体系结构里的互连。到了多机时代成百上千个计算节点要协同工作节点和节点之间也得有“总线”——这就是网络。所以说白了这一章是站在系统设计的角度把网络看成一种“把多个处理器连成一个更大计算机”的手段。学习这一章节的时候建议你把脑子里关于OSI七层模型、HTTP报文之类的印象暂时放一放。你只需要记住一个核心问题两个节点之间传一份数据从发出到收到这条通路上的每一级都在干什么哪一级会成为瓶颈。1.2 分层模型的体系结构解读每一层都在解决什么问题说到网络就绕不开分层。教材里必然会出现ISO/OSI或TCP/IP分层模型但体系结构课程讲分层重点不是让你背“传输层负责端到端、网络层负责路由”而是理解分层的本质每一层都在向上层屏蔽一种复杂性。物理层解决的是“怎么把0和1变成长途信号传出去”可能是电压、光脉冲也可能是无线电波。链路层解决“相邻两个节点之间怎么可靠地传一帧数据”所以有MAC地址、有以太网帧、有重传机制。网络层解决“数据怎么从源头走到目的地”引入了IP地址和路由协议节点之间的路径不再是直连。传输层解决“两个进程之间的数据怎么准确到达”于是有了端口、序列号、确认和重传。从体系结构的角度看这个分层结构最妙的地方在于每一层只需要对相邻层提供固定接口内部怎么实现可以随时替换。比如你的应用用的是IPv4地址底层从以太网换到Wi-Fi再换到5G应用根本无感知。这就好比CPU的指令集架构和微架构的关系——架构稳定微架构随便折腾。但分层也有代价这个代价在性能章节里会反复出现每一层封装、解封装都有开销。数据从一个层传给另一个层要复制、要校验、要计算校验和这些全都是CPU周期。所以后面要讲的协议栈卸载、RDMA、DPU本质上都是在压缩或绕开这些分层开销。2. 网络协议栈与CPU的协作才是本章真正的硬核2.1 网卡、DMA、中断与轮询数据是如何进入内存的如果你只想从这一章里带走一个最核心的硬件流程那就是“数据包从网线到应用进程的内存”全过程。我拿真实场景拆开讲。网卡收到一个数据帧后首先要做链路层校验确认帧没损坏然后确定这个包是不是发给自己的。接下来最关键的一步网卡通过DMA直接存储器访问把数据写进内存的某个缓冲区。注意这个过程不需要CPU参与搬运否则CPU早就被网络流量打满了。DMA写完之后网卡需要通过某种方式通知CPU“数据已经准备好了”。传统方式就是触发中断。中断的好处是CPU能第一时间响应坏处是如果网络流量特别大比如每秒几十万个包CPU就会被中断淹没在“频繁打断—处理—返回”的恶性循环里。所以现代网卡普遍支持中断合并interrupt coalescing把多个包的中断攒一攒一次性通知CPU。再有就是NAPI这种轮询模型——在高流量场景下干脆关掉中断CPU主动去网卡队列里批量取包。实测下来网卡中断从“来一个包打一次”改成“攒一批批量处理”CPU占用能下降一个量级代价是单包延迟会稍微高几十微秒。低延迟场景和高吞吐场景的取舍这就是最典型的例子。2.2 协议栈卸载与Smart NIC为什么卸载后性能能翻倍理解了DMA和中断再往下就会遇到一个天然的性能瓶颈如果每个包都要CPU去做TCP校验和计算、分片重组、以及协议头解析那么CPU就没办法干别的了。于是出现了越来越多的硬件卸载能力。最早是checksum offload网卡帮你算TCP/UDP校验和省掉一次全包遍历然后是TSO/GRO大块数据让网卡自己拆成多个以太网帧发送接收端合并后再交给协议栈再后来是RSS多队列网卡硬件根据哈希把流量分散到多个接收队列每个队列由不同的CPU核处理这样多核系统的并行能力就被压榨出来了。这些机制加一起效果有多明显我做过一个对比测试一台普通的双路服务器关掉所有卸载特性纯靠CPU跑千兆网络都费劲CPU占用居高不下打开TSO、GRO、RSS这些标准卸载后跑满万兆线速CPU占用反而下来了。这就是硬件把软件从重复劳动里捞出来的典型例子。体系结构这门课讲“硬件/软件协同”这里就是最鲜活的教材。2.3 缓存一致性视角下的网络访问DMA与Cache一致性还有一个很容易被忽略、但考试和实际排查都喜欢出题的点DMA写入内存的数据和CPU的Cache之间可能不一致。什么意思CPU读数据首先看Cache如果Cache里缓存了这个地址的旧数据而DMA已经把新数据写进物理内存了CPU读到的却是Cache里的老味道那程序拿到的就是过期数据。这是多处理器系统里老生常谈的一致性问题的“DMA版变种”。解决思路通常有两类。一类是软件层面保证驱动在做DMA传输之前显式flush掉相关Cache行或者用DMA一致性内存映射接口分配内存保证这块内存不被Cache乱缓存。另一类是硬件层面网卡和内存控制器走同一个一致性域DMA写入会自动参与缓存一致性协议让对应Cache行失效。现在的服务器基本都靠后者兜底但嵌入式场景、老旧驱动里Cache不一致导致的数据 corruption问题仍然时有发生。这一小节其实就是在提醒你网络子系统不是一个独立王国它和你学的存储层次、缓存一致性、多核协同是强耦合的。学这一章最好的方式就是拿自己熟悉的系统知识去对照。3. 网络性能度量你这网络到底快不快别光看带宽3.1 带宽、延迟、吞吐量之间的区别和制约关系进入性能部分先把三个概念掰扯清楚因为面试、考试、实际排查都绕不开。带宽Bandwidth链路的理论最大传输速率单位是bps或B/s。它由物理层决定了比如千兆网卡带宽就是1Gbps。延迟Latency一个数据包从发送方到接收方所花的时间单位是毫秒或微秒。延迟包含传输时延、传播时延、处理时延和排队时延。吞吐量Throughput实际上成功传输数据的速率通常小于带宽因为协议开销、丢包重传、拥塞控制都会拉低它。一个最常见的认知误区是“带宽高响应快”。拿硬盘类比就明白了一块SATA SSD顺序读速度500MB/s但随机读延迟可能高达几十微秒一块傲腾持久内存顺序带宽可能没那么夸张但随机访问延迟低到几百纳秒。网络也一样从北京到上海的光缆带宽再高光信号物理极限就摆在那来回一次也要几十毫秒。延迟和带宽是两个独立维度不能互相替代。还有一个容易被忽略的组合指标带宽延迟积BDPBandwidth-Delay Product。它表示“链路上最多能承载多少数据”公式是带宽乘以RTT往返时间。比如带宽10Gbps、RTT为20msBDP就是10Gbps × 0.02s 25MB。这意味着发送方窗口没到25MB之前管道根本填不满TCP的吞吐量上不去。这也是为什么高带宽长距离传输场景要调大TCP缓冲区的原因。3.2 实操用ping、iperf、traceroute给网络做一次体检光讲概念不落地等于白说。我自己的习惯是拿到一台“感觉网络不对劲”的机器按下面这套动作给它做体检。第一步先ping本地网关看基础延迟和丢包。如果网关都ping不通或者延迟抖动巨大先解决链路层问题别往上排查。第二步ping远端地址对比RTT。比如ping网关0.3msping同城服务器5msping跨省服务器30ms这些数值都在合理区间的话链路基本健康。第三步用iperf测TCP吞吐。服务端跑iperf3 -s客户端跑iperf3 -c ip -t 30 -P 8用8个并发流把吞吐打满。如果测出来的吞吐远低于带宽就要考虑是不是TCP窗口太小、有没有丢包重传、网卡协商速率是否正常。第四步全路径诊断用traceroute。它能看到每一跳的延迟帮你定位瓶颈到底在哪个路由器。不过要注意某些路由器对ICMP不响应是正常现象不一定是故障。这一套下来网络大头基本心里有数了。剩下的细节问题比如TCP重传率、握手耗时、队列长度就要借助抓包工具或者ss -i这类内核统计命令。3.3 几个影响网络性能的隐藏因素中断合并、协议栈参数、网卡选项关于网络性能我最常跟人强调的一句话是瓶颈往往不在链路上而在端系统的软件栈里。以下几个隐藏因素都是我在实际环境中踩过坑后总结出来的。第一是中断合并参数。前面提到现代网卡支持中断合并但不同驱动对延迟和吞吐的权衡不一样。默认配置通常偏吞吐导向会把多个包合并后再上报CPU导致单包延迟变高。低延迟场景比如高频交易、实时音视频需要调低或关闭合并代价是CPU占用上升。反过来纯大数据传输场景则可以把合并调高让CPU更省。第二是TCP协议栈参数。默认的发送/接收缓冲区大小通常是为“通用场景低内存占用”设计的。BDP很大的链路如果不调大缓冲区吞吐量会严重受限。生产环境里我一般会把net.core.rmem_max、net.core.wmem_max以及net.ipv4.tcp_rmem、tcp_wmem都调大一些。第三是网卡队列数量与RSS哈希。多队列网卡如果不能充分利用多核中断就会全部打在一个核上形成“单核网络瓶颈”。用ethtool -l看队列数用ethtool -x看RSS配置必要时调整哈希因子把不同连接分散到不同队列。还有一个经常被忽视的电源管理。服务器CPU进入节能状态后网卡中断响应延迟会显著升高。跑性能测试前把CPU governor设成performance模式结果可能立刻不一样。我见过不少“网络延迟忽高忽低”的线上问题最后查出来就是CPU频率动态调节在捣乱。4. 组网层面拓扑结构里的体系结构思想4.1 从总线到交换网络拓扑的演进逻辑把视角从单机拉远到多机第一个值得琢磨的问题是一堆机器怎么连在一起早期最简单的方式就是共享总线所有机器挂到同一条线上谁发数据谁占用总线其他节点监听。这和单机里多设备共享总线的思路一脉相承缺点是带宽被所有节点瓜分节点一多就拥塞。后来演进到交换式网络每个节点通过网线连到交换机交换机内部有交换矩阵可以多条链路同时转发。这就像从共享总线升级到了交叉开关——同一时刻可以有多个设备并行通信总吞吐量大幅提升。这里面的设计思想几乎就是CPU里总线仲裁和Crossbar结构的翻版。继续往大规模走单台交换机端口数有限于是有了多级交换网络比如Clos网络、胖树拓扑。这些结构和多处理器系统里的多级互连网络Omega网络、蝶形网络高度相似本质都是用少量小规模交换机构造出一条低延迟、高带宽、可扩展的规模化网络。4.2 数据中心里的胖树拓扑和等价多路径现代数据中心的网络拓扑里最典型的就是胖树Fat-Tree结构。它分核心层、汇聚层、接入层三层每台服务器接在接入交换机上接入交换机往上连接到汇聚交换机再往上是核心交换机。为什么说它“胖”因为越往上层的链路数越多、聚合带宽越大保证任何两台服务器之间的通信带宽都不会因为上行口不够而缩水。这个思想其实可以类比到片上网络NoC里的网格拓扑——很多核心通过路由节点连接路径多样避免单一瓶颈。胖树拓扑还有一个连带好处任意两台服务器之间存在多条等价路径。于是出现了ECMP等价多路径技术让哈希算法把流量分散到多条平行链路上。这就像前面讲的多队列RSS单连接带宽受限时多路径并行能把总吞吐摊上去。我自己画网络拓扑图时有个习惯不会只看物理连接关系一定会把链路带宽、流量方向和瓶颈点标出来。因为物理拓扑只是骨架真正的价值在于看懂数据会往哪些方向汇聚。核心交换机的下行链路、接入交换机的上行链路永远是拥堵高发区画图时这些位置值得标红。5. 常见网络问题与排查技巧实录5.1 典型场景慢、卡、断怎么一步步定位网络问题几大类最常见的就是慢、卡、断。我每个场景都复盘一遍自己的处理套路。“慢”一般指吞吐上不去。这种问题先看协商速率ethtool eth0确认网卡当前跑在1G还是10G。别笑网线质量差、接口松动导致降级到百兆的例子我见过太多次。速率没问题再跑iperf测吞吐重传率高就抓包看是不是有乱序或丢包。“卡”一般指延迟抖动大时好时坏。这种首先怀疑拥塞或重传。用ping -f看高负载下是否丢包再ss -ti看活动连接的RTT和重传计数。如果TCP重传持续出现则用小流量ping确定大概哪些跳延迟高再结合traceroute定位。记住经验三层路由器的队列拥塞是延迟抖动的头号来源。“断”一般指连接中断或时通时不通。优先怀疑链路层问题比如网线松动、光模块故障、双工模式不匹配。硬件层面没问题再检查二层有没有环路、三层有没有路由黑洞。典型场景是防火墙会话老化、负载均衡后端探活失败导致后端被摘除这类问题不抓包很难看出来。5.2 快速故障排查速查表为了方便参照我把自己常用的排查命令整理成一个速查表方向和命令都写在里面。排查方向常用命令关注点网卡状态ethtool eth0速率、双工、Link detected中断分布cat /proc/interrupts是否集中在单个CPU核队列与RSSethtool -l / ethtool -x队列数、哈希分布吞吐实测iperf3 -c -t 30与实际带宽对比RTT与丢包ping -c 100avg RTT、loss百分比路径探测traceroute -n每跳延迟与丢包TCP连接指标ss -tiRTT、cwnd、retrans协议栈统计netstat -s重传率、乱序包、丢包抓包分析tcpdump -i eth0 host重传、重复ACK、握手耗时这套组合拳打下来绝大多数“网络慢/卡/断”的问题都能定位出方向。不少情况最后发现根本不是网络本身的问题而是端系统的协议栈参数、驱动版本、CPU调频策略在拖后腿。这也是我在文章里反复强调的一个理念网络故障排查本质上是在排查整个计算机系统里所有和网络相关的环节。6. 聊点进阶RDMA、DPU与网络的未来6.1 RDMA为什么能颠覆传统网络协议栈学完传统协议栈的数据通路你大概已经能感受到一个矛盾每多一层封装/解封装就多一次拷贝和计算每来一个包就打断一次CPU多核再怎么分担也架不住大规模分布式场景的千兆万兆流量。RDMA远程直接内存访问的思路极其“体系结构”既然CPU参与协议栈处理太贵那就通过网络硬件完全绕过CPU直接在内存和内存之间搬数据。网卡硬件自己完成可靠性传输、流控、报文重组应用程序只需要把源内存地址、目的内存地址、长度告诉网卡剩下的全部由硬件代劳。不仅传输过程中CPU零参与甚至接收端应用程序的Buffer都由网卡直接Write进来真正实现了“Zero Copy”。性能差距是实打实的。传统TCP在当前服务器上跑出几十微秒级延迟就算不错了而RoCEv2这类基于以太网的RDMA能把延迟压到几微秒以内CPU占用几乎可以忽略不计。这也是它在高性能计算、分布式存储、AI训练集群里越来越吃香的根本原因。6.2 从网卡到DPU网络正在接管系统的控制面RDMA把数据通路卸载掉了但网络的功能远不止数据传输。虚拟化云环境里租户隔离、虚拟网络转发、安全组策略、存储虚拟化这些任务全部交给CPU做会消耗大量核数。这就催生了DPU数据处理单元或叫SmartNIC的概念。简单理解DPU就是在网卡硬件上内置了一套完整的CPU子系统通常是一组ARM核和专用的加速引擎把网络、存储、安全这些基础设施任务从主机CPU上整体搬走。主机CPU只跑用户业务网络虚拟化、存储协议处理、报文过滤、加密解密全在DPU上完成。我接触DPU之后最大的感触是体系结构教材里“I/O设备靠中断请示CPU干活”的经典图景正在被“I/O设备自己就是一台小计算机反过来替CPU分担负载”的新图景替代。这其实是对“体系结构”这个概念最好的注脚——站在系统全局做权衡把合适的任务放到合适的处理单元上去。说回第七章这一章它表面上在讲网络实际上在帮你建立一种“全局系统观”数据从网线进来之后每一次拷贝、每一次协议栈处理、每一次中断调度背后都是体系结构里存储层次、多核并发、I/O子系统的协同。把这章读通了你不仅能把网络性能问题看得更透对整个计算机系统的理解也会上一个台阶。我个人学完这章后最大的变化是遇到任何“网络慢”的报障不再第一时间怀疑玄学而是顺着从网卡到内存再到CPU的这条路一寸一寸找原因。这个思维习惯比记住任何一张协议图都值钱。