真正拖慢AI的,不是计算,而是数据与设备之间的“语义距离”
Hatched by Kevin Di
Aug 16, 2026
1 min read
1 views
94%
你是否见过这样的悖论:一个深度学习层几乎不需要计算,却可能比最复杂的矩阵乘法更容易拖慢整张芯片?真正决定系统速度的,有时不是处理器能做多少运算,而是一个值从产生到被使用,究竟要经过多少次搬运、登记、确认和等待。
这揭示了一个常被忽略的事实:现代计算机的核心问题,正在从“算得够不够快”转向“数据能不能以足够低的协调成本抵达正确的位置”。 内存带宽、缓存一致性、设备互联和软件队列,看似属于不同的技术领域,实际上都在回答同一个问题:数据的生产者与消费者,彼此离得有多远,以及系统需要付出多少代价才能让它们协作。
最慢的部分,往往不是最会计算的部分
深度学习中的归一化、激活函数和池化层,通常每个输入只需要少量计算。它们不像矩阵乘法那样,能够对同一批载入的数据反复进行大量运算。数据从内存读入后,很快就被处理完,又必须写回去。于是,性能不再由算术单元决定,而由数据传输时间决定。
可以用一个简单的比喻理解这种差异。矩阵乘法像是一家工厂:原料一旦运进车间,就会被反复加工很多次,运输成本被大量计算摊薄。归一化或激活层则像是给每件商品贴标签:工人真正做的动作很少,但每件商品都必须从仓库取出,再送回仓库。如果仓库距离车间很远,那么工人越熟练,整个流程也未必越快,因为瓶颈已经变成了往返运输。
这就是所谓的算术强度问题。一个操作所执行的计算量,相对于它需要搬运的数据量越少,就越容易受到内存系统限制。此时,单纯增加计算核心、提高时钟频率,甚至使用更强大的算力,都可能收效甚微。工厂里增加工人,并不能缩短仓库与车间之间的距离。
但这里还有一个更深的层次。数据搬运不只是物理上的复制,它还包含了系统协调数据的方式。数据在哪里?谁拥有它?谁可以读取它?修改之后,哪些参与者需要知道?这些问题的答案,会决定一次访问是像普通指令一样自然,还是必须经过一整套软件和硬件流程。
当计算量很少时,系统真正支付的不是“计算费”,而是“让数据可以被计算的协调费”。
从搬运数据到直接使用数据
传统设备互联经常把设备看成一个外部参与者。应用先在内存中准备任务描述,再通知设备开始工作。以远程直接内存访问为例,一次发送并不是简单的“把数据交给网卡”。软件需要生成工作队列元素,然后通过门铃通知网卡。网卡收到通知后,再从内存取出任务描述,根据其中的地址访问数据,完成数据搬运,接收方写入远端内存,之后返回完成消息。发起方网卡还要生成完成队列元素,应用最终通过轮询才能知道任务结束。
这种机制并非没有价值。它适合大块数据、异步传输以及吞吐量优先的场景。当一次操作搬运很多数据时,队列和通知的固定成本可以被摊薄。然而,对细粒度访问而言,情况完全不同。假设一个程序只需要远端内存中的一个数值,或者一个设备只需要读取某个小对象,那么为这次访问建立任务、敲门、等待完成,再轮询结果,就像为了取一枚螺丝,先填写运输申请,通知仓库,再等待仓库发送回执。
支持缓存一致性的互联协议改变了抽象模型。它允许主机内部的处理器和设备,在更接近普通内存访问的语义下协作。CPU或GPU发出一次加载或存储指令,互联模块负责把请求送到对方,对方完成相应的数据访问,结果返回后,原来的指令才继续执行。中间仍然存在网络报文和DMA,但应用不必显式管理工作队列、门铃和完成队列。
这里的关键不只是少了几步,而是复杂性从软件显式流程转移到了硬件所理解的内存语义中。对程序员而言,远端数据不再必须先变成一个需要调度的“任务”,它可以表现为一个能够被读取或写入的地址。访问者和被访问者之间的距离没有消失,但距离不再强迫应用改变自己的思维方式。
这也解释了为什么缺乏缓存一致性时,即使设备内存理论上已经可以映射到主机地址空间,实际性能仍可能糟糕得不可接受。一个通过PCIe映射的设备内存区域,如果不能被正常缓存,CPU的每次访问都可能需要穿过互联链路到设备端完成。原本几秒钟可以完成的系统启动,可能因此变成数十分钟。问题并不是CPU不会执行这些指令,也不是设备完全不能提供内存,而是每一次细小访问都承担了极高的远程协调成本。
缓存一致性,本质上是缩短“语义距离”
人们常把缓存一致性理解成一个硬件正确性问题:多个处理器或设备看到的数据必须保持一致。但从系统设计角度看,它更像是一种降低协作摩擦的接口。
设想两位工程师共同编辑一份文档。没有一致性机制时,每次修改都要先导出文件、发送给对方、等待对方确认,再决定自己是否可以继续工作。即使网络带宽很高,这个过程依然会因为确认和协调而缓慢。支持一致性的共享文档则允许双方直接读取和修改共同状态,系统在后台处理缓存、失效和所有权问题。它不一定让每一次传输的物理距离变短,却让参与者不必反复管理传输过程。
在计算系统中,缓存一致性同样不能凭空创造带宽,也不能让远端访问变成本地访问。它解决的是另一个问题:如何让多个计算单元以更自然的方式共享数据,而不要求应用显式编排每一次细粒度交换。 对CPU和设备之间的通信而言,这种语义尤其重要,因为许多工作负载并不是整批搬运,而是大量小规模、不可预测、彼此依赖的访问。
这正是内存受限层与设备互联技术之间的深层连接。归一化、激活和池化之所以容易受内存限制,不仅因为它们搬运数据多,也因为它们常常缺少足够的计算来掩盖搬运和同步的开销。如果中间结果必须频繁离开高速存储层,或者在CPU与GPU之间来回切换,那么每一个低算术强度操作都会暴露互联的延迟与协调成本。
因此,优化这类层不能只问:“怎样让核心算得更快?”还要问:
- 数据是否被重复写入和读取?
- 相邻操作能否融合,让中间结果留在片上?
- 生产者和消费者是否被放在了不必要的两端?
- 一次访问是否大到足以摊薄队列、通知和同步成本?
- 如果访问必须细粒度,互联是否提供了接近加载和存储的语义?
这些问题把模型优化从算子层面推进到了系统层面。一个看似普通的激活函数,可能因为前后算子融合而显著提速;一个看似强大的加速器,可能因为每次访问都需要显式协调而在小数据任务上表现糟糕。
一个统一框架:数据移动的三种成本
分析异构系统时,可以把数据移动成本拆成三个部分:距离成本、批处理成本和语义成本。
距离成本是数据跨越内存层级、芯片边界或设备边界所需要的带宽与延迟。片上缓存、显存、主机内存和远端内存之间存在不同的物理距离。数据越远,通常越难以低延迟访问。
批处理成本是为了提高吞吐量而引入的组织成本。队列元素、门铃、完成消息和轮询,都属于这一类。它们对大块异步传输很有意义,因为固定开销可以摊薄;对单个小数据访问却可能成为主要成本。
语义成本则是最容易被忽略的一项。它指的是应用为了让系统知道“要做什么、数据在哪里、何时完成”而必须承担的协议复杂性。一次普通的加载指令,通常由硬件自动完成地址访问和必要的缓存处理。一次显式DMA操作,则可能需要应用创建描述符、通知设备并处理完成事件。
可以用一个粗略公式表达:
总成本 = 距离成本 + 批处理成本 + 语义成本
当数据量很大时,距离成本和带宽占主导,异步DMA与批量传输通常更有效。当数据量很小、访问模式分散、依赖关系密集时,批处理成本和语义成本就会迅速上升。此时,类似CXL或NVLink所提供的加载与存储访问方式,价值不只是峰值带宽,而是减少了应用必须显式管理的步骤。
这个框架也能解释一个经常出现的误判:某种互联的理论带宽很高,却不一定适合所有工作负载。带宽描述的是一条高速公路每小时能运多少货物;延迟描述的是一辆车从出发到抵达需要多久;语义成本则描述了发货前要填多少表、盖多少章。小对象、高频率、强依赖的访问,常常更在意后两者。
从“更强算力”转向“更近的数据”
对于模型开发者和系统工程师而言,这种认识可以转化为一套立即可用的决策原则。
首先,先测量数据移动,再解释计算时间。不要只看算子执行了多少浮点运算,还要观察内存读写量、缓存命中率、设备间传输、同步次数以及中间张量的生命周期。一个算子如果每次只执行很少计算,却反复读写大张量,就应优先从数据布局和融合入手。
其次,把相邻的低算术强度操作尽可能融合。归一化、激活、缩放和裁剪如果分别启动多个内核,就可能反复把同一数据写回并重新读取。融合的价值不是减少几条算术指令,而是让中间结果不必离开更快的存储层。
再次,根据访问粒度选择通信模型。大块、连续、可预期的数据传输,适合批量DMA和异步队列。小块、细粒度、具有数据依赖的访问,则需要更低的语义开销和更接近加载与存储的接口。不要因为某种协议吞吐量高,就把它用于所有通信模式。
最后,把设备互联视为编程模型的一部分,而不只是硬件规格。支持一致性的互联能够降低主机与设备之间的语义距离,但它不意味着所有数据都应该共享,也不意味着所有访问都适合远端执行。真正重要的是判断哪些数据需要共享、哪些数据应该复制、哪些数据最好留在生产者附近。
Key Takeaways
- 先判断瓶颈属于计算、带宽还是协调。 低算术强度层通常受内存传输限制,而细粒度异构访问还可能受队列、通知和完成确认限制。
- 优先减少中间数据的往返。 算子融合、合理的数据布局和片上缓存驻留,往往比单纯增加计算核心更有效。
- 大数据用批量,小数据用低语义开销。 DMA和异步队列适合大块传输,加载与存储语义更适合细粒度、依赖密集的访问。
- 不要只比较理论带宽。 同时评估延迟、缓存行为、同步次数以及应用需要显式管理的协议步骤。
- 把“数据在哪里”作为架构问题。 最好的优化有时不是加速一次计算,而是让生产者和消费者根本不必相隔太远。
真正先进的计算系统,并不只是拥有更多算术单元,而是让数据更少搬运、更少等待、更少解释。深度学习中的内存受限层提醒我们,计算很容易被数据移动拖住;缓存一致性和加载与存储互联则进一步提醒我们,数据移动本身还会被协调机制拖住。
所以,下一次面对一个性能问题时,不妨先不要问“这颗芯片还能算多快”。先问三个更尖锐的问题:数据为什么要移动?为什么必须由软件显式协调?生产者和消费者为什么不能以更接近共享内存的方式直接相遇?
当系统设计开始围绕这些问题展开,性能优化就不再只是给机器增加马力,而是在重新设计数据相遇的方式。计算的未来,可能不属于最会计算的系统,而属于最懂得减少距离、批次与误解的系统。
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣