当CPU等数据等到打哈欠:近存计算到底救不救得了内存墙?
前阵子调一个数据库扫描任务,profiler一开,我差点笑出声。CPU利用率28%。DRAM带宽95%。延迟曲线像心电图。十亿行数据,扫完只吐出一个sum和几个过滤后的ID。你说气不气人。数据从内存搬到CPU,算两下,扔掉。搬运比计算贵得多。
这就是我盯上近存计算的切口。不是因为它热,是因为这个场景太典型:算力闲着,内存通道堵着。把计算单元往内存旁边挪,少搬一点,哪怕只少搬一半,系统行为都可能变。
DRAM近存计算内存墙数据搬运带宽瓶颈示意图
先把话说死:近存计算不是魔法。它救不了所有负载,也替代不了HBM、CXL、缓存层次。可它确实戳中了一个老问题——内存墙。
内存墙不是墙,是收费站排队
内存墙不是墙,是收费站排队
冯诺依曼架构里,CPU和DRAM隔着总线。CPU算得快,DRAM给得慢。这个差距这些年没缩小,反而被AI、推荐系统、图计算拉大了。片外访存的能耗,比片上ALU做一次运算高几个数量级。别小看这几个数量级,数据中心里电费和散热会替你记住。
内存墙这个词听着像一堵墙。其实更像收费站。数据不是过不去,是要排队、要交费、要来回跑。带宽不够时排队,延迟高时空等,搬运多时费电。CPU核越多,排队越壮观。
传统办法是堆缓存、堆HBM、堆预取。有用。但缓存命中率不是许愿池。HBM贵,容量也有限。预取猜错,反而添乱。于是有人想:既然数据要过来,能不能让计算也过去一点?
近存计算,near-memory computing,说白了就是把一小块计算逻辑放到内存旁边。注意,是旁边。不是把CPU塞进DRAM阵列,也不是把SRAM变成模拟计算阵列。后者更接近存内计算,in-memory computing。两个词经常被混着用,我见过不少方案介绍里自己都写串。
近存计算的算盘很直接:利用内存内部更高的带宽和更低的搬运开销,在数据离开内存之前做掉一部分活。比如过滤、聚合、查表、点积。返回的不是整箱数据,而是压缩后的中间结果。
把切菜台搬到仓库门口,而不是把刀埋进米缸
我常用一个不太精确的比喻。厨房是CPU,仓库是DRAM。以前做菜,整箱菜从仓库搬到厨房,挑几颗葱,剩下的再搬回去。近存计算像在仓库门口支一张切菜台。葱在门口挑,菜叶在门口扔,只把切好的小篮子送进厨房。
切菜台不是厨房。它干不了复杂宴席。但它能干掉大量重复、规则、带宽敏感的粗活。
落到芯片上,常见做法是在DRAM bank旁边、HBM堆栈的die里、或者DIMM上放计算单元。HBM-PIM的思路是在HBM堆栈里加计算逻辑,利用TSV和bank内带宽,让一部分乘加在内存侧发生。UPMEM那类DIMM方案更激进,在内存条上放多个小核,每个核管一片DRAM,跑自己的指令。还有CXL内存池旁边挂加速器,算不算近存?广义算,边界有点糊。
HBM近存计算内存堆栈PIM计算单元封装剖面图
原理不神秘。难的是让数据布局、指令流、一致性、编译器一起配合。举个例子,推荐系统的embedding lookup。一次请求查几百个向量,每个向量做点积。算术强度不高,但数据量吓人。CPU把向量从内存搬到缓存,再算几十个乘加。搬运占大头。近存计算可以让内存侧做gather和部分点积,返回分数。听上去顺。
数据库过滤也一样。谓词下推喊了很多年,从SQL下推到存储引擎。近存计算把下推再往下推一层,推到内存侧。十亿行里筛出几千行,何必把十亿行都搬过去?图计算的稀疏矩阵向量乘也类似,邻居列表在内存里,算到哪取到哪。
但注意,近存计算适合的是规则并行、低算术强度、高带宽需求的活。复杂控制流、随机依赖、需要强一致性的活,别硬塞。切菜台做不了雕花。
别急着欢呼,坑在软件栈和一致性
别急着欢呼,坑在软件栈和一致性
我见过一个POC,纸面加速比很好看。真跑起来,前两周全在调数据布局。热点数据没落在带计算单元的内存分区里,CPU和内存侧来回同步,性能像坐过山车。后来改分区策略,加速比从1.1爬到1.6,团队已经累瘫。你说值不值?看场景。要是这个负载占数据中心三成机时,值。要是只占百分之三,先别上头。
近存计算的坑,硬件只是一半。另一半在软件。
编程模型碎片化是头一道坎。每家SDK不一样,数据要显式分区,kernel要写两套,调试工具还不齐。虚拟内存和页迁移会捣乱。缓存一致性更麻烦,CPU改了内存侧还在算旧值,这种事一出就是深夜排障。
还有利用率和散热。内存侧计算单元算力不大,干太复杂的活不划算,干太简单的活又喂不饱。HBM堆栈里加逻辑,热密度上去,封装和良率都要钱。DIMM方案插槽功耗和容量密度也要权衡。别只看峰值带宽,看真实吞吐和尾延迟。
常见误解得拆几个。近存计算不是存内计算,它没把存储阵列变成计算阵列。近存计算不是替代HBM,它更像在HBM/DRAM旁边加一层分流。近存计算不是通用加速器,它挑负载。还有人以为把计算放内存边就自动快了。不会。数据搬得少才算数,搬得乱照样堵。
边界很清楚:算术强度高的负载,计算本身是瓶颈,搬过去收益有限。控制流复杂的负载,内存侧小核跑不动。需要全局一致性的负载,同步开销会吃掉收益。数据局部性差、随机访问多的负载,先回去优化数据布局,别拿近存计算当止痛药。
说到底,近存计算是系统架构手术,不是买张卡插上就完事。先看profiler。CPU利用率低、内存带宽打满、数据搬运占大头,再考虑。否则,先回去改索引、改分片、改数据格式。真的。
内存墙不会消失。近存计算也当不了银弹。它只是把一部分搬运费省在收费站门口。省得下来,就是好工程。省不下来,别硬吹。