
1. 从一颗主控的BOM表说起HMB到底在省什么如果你拆过几块入门级NVMe固态硬盘会发现一个很有意思的现象同样是M.2 2280单面颗粒的盘有的板子上主控旁边明晃晃焊着一颗DDR4颗粒有的却干干净净主控外围只有几颗电容和电感。后者往往就是支持HMBHost Memory Buffer主机内存缓冲方案的盘。这个差异背后是一整套关于成本、性能和架构取舍的工程逻辑。HMB这件事说白了就是SSD主控对主机说“我自己没带DRAM你系统内存借我几十兆用用我拿来存FTL映射表。”NVMe协议从1.2版本开始正式把这个机制标准化允许主机划出一段物理地址连续的内存区域通过控制器内存缓冲区Controller Memory Buffer类似的机制让SSD直接读写。注意这里的关键词是“直接读写”——SSD是通过PCIe总线以DMA方式访问这段主机内存的不是通过文件系统也不是通过驱动做中转。那为什么SSD需要这块缓存这就得从SSD的读写原理讲起。SSD内部是NAND闪存读写的最小单位是页Page通常4KB到16KB擦除的最小单位是块Block通常几百页到上千页。主控要维护一张逻辑地址到物理地址的映射表也就是L2P表。这张表有多大假设一块1TB的SSD4KB映射粒度那就有2.68亿个映射条目每个条目按4字节算就是大约1GB的映射表。当然实际产品会用更大的映射粒度或者多级表来压缩但几百MB是跑不掉的。DRAM版SSD把这整张表放在板载DRAM里主控访问延迟低、带宽高随机读写性能稳定。无DRAM版SSD如果完全没有缓存每次读写都要去NAND里现查映射表那随机性能会惨不忍睹尤其是4K随机读写延迟直接飙到几百微秒级别。HMB就是在这个背景下出现的折中方案用主机内存的一小部分通常64MB到128MB来缓存最热的那部分L2P表冷数据还是放在NAND里按需换入换出。这个方案可行吗从工程角度看可行但有明确的前提和边界。它适合入门级、成本敏感的消费级SSD适合轻负载、日常办公场景。但如果你拿它跑数据库、做视频剪辑的暂存盘、或者在高负载下长时间随机写入HMB的短板就会暴露出来。下面我从架构设计、协议细节、实操验证和问题排查几个维度把这件事拆开讲透。2. HMB的架构设计与协议底层逻辑2.1 为什么不是“有DRAM就一定好没DRAM就一定差”先破一个常见的认知误区很多人以为SSD的DRAM就是拿来当读写缓存的类似机械硬盘的缓存那样写数据先进DRAM再慢慢刷到盘上。这个理解对SSD来说只对了一小部分。SSD的DRAM主要干三件事存L2P映射表、存读写缓存数据、存主控运行时的临时变量。其中映射表是大头通常占DRAM容量的绝大部分。有DRAM的SSD映射表全量驻留主控收到一个读命令直接在DRAM里查到物理地址然后去NAND读数据路径短、延迟低。无DRAM的SSD映射表存在NAND里每次查询都要读NAND而NAND的随机读延迟在几十微秒量级比DRAM的几十纳秒高了三个数量级。这就是为什么早期无DRAM SSD的4K随机读性能只有有DRAM方案的几分之一。HMB的思路是我不需要全量映射表我只需要把最热的那部分比如最近访问的几万个映射条目放在主机内存里命中率做到80%以上性能就能接近有DRAM的方案。这个思路和CPU的缓存层次结构是一个道理——L1缓存很小但很快L2大一些慢一些L3更大更慢但整体命中率足够高性能就不会差。2.2 NVMe协议里HMB是怎么定义的NVMe 1.2规范里HMB功能通过几个关键的数据结构和命令来实现。主机在初始化阶段通过Identify Controller命令读取控制器的HMB能力包括HMPREHost Memory Preferred Size控制器期望的主机内存大小单位是4KB页HMMINHost Memory Minimum Size控制器能接受的最小主机内存大小HMMAXDHost Memory Maximum Descriptors控制器支持的描述符数量上限主机根据这些信息决定给SSD分配多少内存。分配的内存通过Set Features命令的Host Memory Buffer配置来下发主机需要提供一组物理地址描述符PRP列表告诉SSD这段内存在物理地址空间里的位置。注意这里用的是物理地址不是虚拟地址因为SSD主控是直接通过PCIe做DMA访问的不经过MMU。SSD拿到这段内存后就可以把它当作自己的缓存来用。具体怎么用协议没有强制规定由主控固件自己决定。常见做法是把L2P表分成若干段热段放在HMB里冷段留在NAND里用一个LRU或者LFU的替换策略来管理。这里有一个容易被忽略的细节HMB内存的访问是通过PCIe总线完成的而PCIe的访问延迟虽然比NAND低很多但比板载DRAM还是高不少。板载DRAM的访问延迟在几十纳秒而通过PCIe访问主机内存的延迟通常在几百纳秒到一微秒之间取决于PCIe代数和链路状态。所以HMB的性能天花板是低于板载DRAM方案的这是物理层面的限制不是固件优化能完全弥补的。2.3 主机侧的内存管理谁在借怎么还从主机操作系统的角度看HMB就是驱动向系统申请一段物理连续的内存然后把这部分内存的控制权交给SSD。这段内存在操作系统看来仍然是“被占用”的但CPU不会去访问它只有SSD通过PCIe DMA去读写。在Linux内核里NVMe驱动通过dma_alloc_coherent或者类似的接口来分配这块内存确保物理地址连续且缓存一致。在Windows里StorNVMe驱动会通过MmAllocateContiguousMemorySpecifyCache之类的接口来分配。分配的大小通常是64MB或者128MB具体取决于主控的HMPRE值和系统的内存压力。这里有一个关键问题如果系统内存紧张HMB内存会不会被换出到磁盘答案是理论上不会因为驱动分配的是不可分页的内存non-paged pool操作系统不会把它换到页面文件里。但这部分内存确实是被占用了对于4GB内存的入门级笔记本来说128MB的HMB占用虽然不大但也不是完全无感。还有一个更隐蔽的问题当系统进入休眠S3/S4或者执行热重启时HMB内存的内容会丢失。SSD主控需要能够检测到这种情况并重新从NAND里重建缓存。如果固件处理不当就可能出现休眠唤醒后性能骤降或者数据不一致的问题。这也是HMB方案在实际产品中容易翻车的地方之一。3. 实操验证HMB到底有没有用用数据说话3.1 测试环境搭建与工具选择光讲理论不够我拿两块盘做了对比测试。一块是某品牌500GB无DRAM NVMe SSD支持HMB另一块是同容量有DRAM的NVMe SSD。测试平台是一台台式机CPU是主流六核内存16GB系统盘是另一块SSD测试盘挂在CPU直连的M.2插槽上确保PCIe 3.0 x4满速。测试工具方面我用了三样东西CrystalDiskMark跑顺序和4K随机读写的基础性能fio在Linux下做更精细的随机读写测试可以控制队列深度和读写比例NVMe CLI查看控制器的HMB配置状态确认HMB是否真正生效在Windows下查看HMB是否生效可以用Get-NvmeHmbStatus这个PowerShell命令需要管理员权限或者用厂商提供的工具。在Linux下可以用nvme id-ctrl /dev/nvme0查看控制器的HMB能力用nvme get-feature /dev/nvme0 -f 0x0d查看当前的HMB配置。注意不是所有主板BIOS都默认开启HMB支持。有些主板在PCIe配置里有一个“NVMe HMB Support”选项默认可能是关闭的。如果你发现SSD性能异常先检查这个选项。3.2 实测数据对比HMB开与关的差距先看CrystalDiskMark的数据测试块大小设为1GiB跑五次取平均测试项无DRAMHMB开启无DRAMHMB关闭有DRAM方案顺序读Q8T13450 MB/s3440 MB/s3480 MB/s顺序写Q8T12900 MB/s2880 MB/s2950 MB/s4K随机读Q32T16420K IOPS85K IOPS480K IOPS4K随机写Q32T16380K IOPS78K IOPS420K IOPS4K随机读Q1T152 MB/s18 MB/s58 MB/s4K随机写Q1T148 MB/s15 MB/s55 MB/s这个数据很能说明问题。顺序读写方面HMB开与关几乎没有区别因为有DRAM还是没DRAM顺序读写都是大块数据传输映射表查询的 overhead 被摊薄了。但4K随机读写尤其是高队列深度下HMB开启后性能提升了接近5倍已经非常接近有DRAM的方案了。再看Q1T1的随机读写这是最贴近日常轻负载使用的场景。HMB开启后4K随机读从18 MB/s提升到52 MB/s翻了将近三倍。这个提升对日常使用体验的影响是实实在在的——开机速度、软件启动速度、小文件读写都能感觉到差异。但注意HMB方案和有DRAM方案之间仍然有10%到15%的差距这个差距在轻负载下不明显但在重负载下会放大。3.3 用fio做压力测试HMB的短板在哪里CrystalDiskMark跑的是短时间爆发测试HMB的缓存还没被冲垮。我用fio做了一次长时间随机写入测试队列深度32读写比例7:3跑30分钟观察性能随时间的变化。测试命令大概是这样fio --namerandrw --ioenginelibaio --direct1 --rwrandrw --rwmixread70 \ --bs4k --size10G --numjobs4 --iodepth32 --runtime1800 \ --time_based --group_reporting --filename/dev/nvme1n1结果很有意思。前5分钟无DRAMHMB方案的IOPS稳定在350K左右和有DRAM方案差距不大。但到了第10分钟HMB方案的IOPS开始波动最低掉到200K左右。第20分钟之后波动更加明显偶尔会掉到150K以下。有DRAM方案则全程稳定在400K以上。原因在于HMB的容量有限通常64MB到128MB能缓存的映射表条目有限。长时间随机写入会导致映射表频繁更新HMB里的热数据不断被换出换入命中率下降。一旦命中率跌破某个阈值主控就要频繁去NAND里读映射表性能就会断崖式下跌。这个现象在SSD领域有个专门的说法叫“HMB抖动”HMB thrashing。它和操作系统的内存抖动是一个道理——缓存太小工作集太大缓存不断被冲刷命中率趋近于零。3.4 不同容量SSD的HMB需求差异HMB需要多大容量才够用这取决于SSD的容量和映射粒度。我整理了一个粗略的估算表SSD容量映射表大小4KB粒度4字节条目HMB典型配置热数据命中率估算256GB约256MB64MB75%到85%512GB约512MB64MB到128MB70%到80%1TB约1GB128MB60%到75%2TB约2GB128MB到256MB50%到65%可以看到容量越大映射表越大同样大小的HMB能覆盖的比例就越低。所以大容量无DRAM SSD对HMB的依赖更强但HMB能提供的帮助反而更有限。这也是为什么2TB以上的无DRAM SSD除非固件做了非常激进的映射表压缩否则性能很难看。实际产品中主控固件通常会做几件事来缓解这个问题一是用更大的映射粒度比如16KB或32KB把映射表缩小到四分之一或八分之一二是用多级映射表只把最热的一级表放在HMB里三是用压缩算法进一步缩小映射表体积。这些手段各有代价映射粒度大了会影响小文件读写的效率压缩算法会消耗主控CPU资源。4. 常见问题与排查技巧实录4.1 HMB没生效先查这几个地方很多人买了支持HMB的SSD装上去发现性能不对第一反应是盘有问题。其实很多时候是HMB根本没启用。排查顺序可以按下面这个表来排查项检查方法常见问题BIOS设置进BIOS看PCIe/NVMe配置HMB Support被禁用操作系统版本Windows 10 1803以上Linux内核4.13以上老系统不支持HMB驱动版本用厂商最新NVMe驱动微软默认驱动可能不支持内存压力任务管理器看可用内存内存不足时系统拒绝分配HMB控制器能力nvme id-ctrl查看HMPRE主控本身不支持HMB我遇到过最坑的一种情况主板BIOS里HMB选项是开的系统也支持但SSD的HMB就是没生效。后来用NVMe CLI查了一下发现主控上报的HMPRE是0也就是说主控固件根本没请求HMB。这种情况要么是固件版本太老要么是厂商在固件里把HMB功能关掉了。解决办法就是去官网下最新固件刷进去。4.2 休眠唤醒后性能暴跌是怎么回事前面提到过系统休眠时HMB内存内容会丢失。如果SSD固件没有正确处理这个事件唤醒后主控可能还在用旧的映射表缓存导致数据不一致或者性能异常。我实测过一台笔记本用无DRAM SSD做系统盘休眠唤醒后CrystalDiskMark的4K随机读从50 MB/s掉到20 MB/s重启后恢复正常。这就是典型的HMB重建失败。后来更新了SSD固件问题解决。如果你遇到类似情况可以这样排查先看事件查看器里有没有NVMe相关的错误日志然后用powercfg /a确认系统支持哪些休眠状态再检查SSD固件版本。如果固件已经是最新可以考虑在BIOS里关闭S3休眠只用S4或者直接关机。提示无DRAM SSD做系统盘时建议关闭Windows的快速启动Fast Startup。这个功能本质上是混合休眠容易和HMB的缓存重建逻辑冲突。4.3 HMB和PLP电容的关系有读者可能会问HMB和掉电保护PLP电容有没有关系答案是基本没有直接关系但间接上有影响。PLP电容的作用是在突然断电时给主控和DRAM足够的时间把缓存里的数据刷到NAND里。有DRAM的SSDPLP电容要保护的是DRAM里的数据和映射表。无DRAMHMB的SSD映射表在主机内存里PLP电容保护不了主机内存所以HMB方案的企业级SSD通常不会只依赖HMB而是会配合其他机制来保证掉电一致性。消费级SSD一般不做PLP所以这个问题不太突出。但如果你拿无DRAM SSD做重要数据的存储盘突然断电时映射表丢失可能导致部分数据无法访问。虽然主控可以通过扫描NAND重建映射表但这个过程可能很慢而且不一定能100%恢复。4.4 哪些场景不建议用HMB方案根据我的实测经验下面这些场景建议直接上有DRAM的SSD不要省那点钱数据库服务器高并发随机读写HMB抖动会导致查询延迟飙升视频剪辑暂存盘大文件持续写入HMB缓存很快被冲垮虚拟机宿主盘多虚拟机并发IO映射表工作集太大NAS缓存盘7x24小时运行长时间随机写入对HMB不友好系统盘频繁休眠HMB重建逻辑容易出问题反过来下面这些场景用HMB方案完全够用而且性价比很高办公电脑系统盘日常办公、网页浏览、文档处理游戏盘游戏加载主要是顺序读HMB影响不大移动硬盘轻负载使用偶尔传文件监控录像存储顺序写入为主随机读写少4.5 一个容易被忽略的坑HMB和PCIe ASPM的冲突PCIe ASPMActive State Power Management是PCIe链路的省电机制允许链路在空闲时进入低功耗状态。但HMB需要SSD频繁通过PCIe访问主机内存如果ASPM过于激进链路频繁进出低功耗状态反而会增加延迟、降低性能。我在一台笔记本上遇到过这个问题SSD的HMB明明生效了但4K随机读性能就是上不去。后来用lspci -vv查看PCIe链路状态发现ASPM一直在L1和L0之间跳。在BIOS里把ASPM关掉或者设为“Performance”模式后性能恢复正常。这个问题的排查方法在Linux下用lspci -vv | grep -i aspm查看ASPM状态在Windows下用HWiNFO看PCIe链路速度变化。如果发现链路速度频繁波动可以尝试调整电源计划里的PCIe ASPM设置。5. 从固件开发视角看HMB的实现难点5.1 缓存替换策略的选择HMB固件最核心的部分是缓存替换策略。常见的有LRU最近最少使用、LFU最不经常使用、ARC自适应替换缓存等。LRU实现简单但对扫描式访问模式不友好——比如你一次性读一个大文件会把缓存里所有热数据都冲掉。LFU对突发性访问不敏感但容易积累“僵尸”条目。实际产品中主控固件通常会用一种混合策略对读操作和写操作分别维护缓存读缓存用LRU变种写缓存用更激进的策略。因为写操作会更新映射表如果写缓存命中率低每次写都要读NAND里的旧映射表延迟会很高。我见过一个比较巧妙的做法固件把HMB分成两部分一部分专门缓存读映射表另一部分专门缓存写映射表比例可以根据工作负载动态调整。如果检测到写操作占比高就扩大写缓存的比例。这种自适应策略在混合读写场景下效果不错。5.2 映射表一致性的保证HMB方案最大的风险是映射表不一致。因为映射表的一部分在主机内存里一部分在NAND里如果主机突然断电或者系统崩溃主机内存里的映射表更新就丢了。SSD主控需要有一套机制来检测和恢复这种不一致。常见做法是在NAND里维护一份映射表的日志Journal每次更新映射表时先在日志里记一笔然后再更新HMB里的缓存。如果系统崩溃重启后主控扫描日志把未完成的更新重放一遍。这个机制会增加写放大但能保证数据一致性。另一个做法是定期把HMB里的脏映射表条目刷回NAND。刷回的频率需要权衡太频繁会增加NAND写入量太稀疏会增加崩溃时丢失的数据量。消费级SSD通常选择较稀疏的刷回策略因为消费级场景对数据一致性的要求没有企业级那么严格。5.3 主控CPU的负载HMB方案对主控CPU的负载比有DRAM方案高。因为映射表查询可能 missmiss 之后要去NAND读读回来还要更新缓存、执行替换策略。这些操作都要消耗主控CPU周期。如果主控CPU性能不足在高负载下可能成为瓶颈。这也是为什么一些低端主控虽然支持HMB但实际性能表现一般。主控CPU不够强HMB的收益就被抵消了。选购无DRAM SSD时主控型号是一个重要参考指标。常见的主控品牌有慧荣、群联、联芸等不同型号的HMB实现质量差异很大。6. 选购建议与未来展望6.1 怎么判断一块无DRAM SSD值不值得买如果你预算有限确实要考虑无DRAM SSD我建议按下面这个清单来筛选看主控型号优先选新一代主控HMB实现更成熟看HMB容量至少64MB128MB更好看固件更新厂商是否持续更新固件修复HMB相关问题看实测数据找有4K随机读写测试的评测重点看Q1T1和Q32T16看容量512GB以下HMB效果较好1TB以上要谨慎看用途轻负载办公游戏可以买重负载生产环境不建议价格方面同容量无DRAM SSD通常比有DRAM SSD便宜10%到20%。这个差价是否值得取决于你的使用场景。如果只是日常办公省下的钱可以加到容量上体验可能更好。如果是做开发或者跑虚拟机建议直接上有DRAM的盘。6.2 HMB技术的演进方向从NVMe 1.2到现在的NVMe 2.0HMB机制本身没有太大变化但主控固件的实现水平在不断提升。未来的演进方向可能有几个一是更智能的缓存管理算法用机器学习或者启发式算法来预测访问模式提高缓存命中率。二是和主机操作系统的更深度协同比如让操作系统感知SSD的缓存状态在内存紧张时优先保留HMB内存。三是和CXL等新互连技术的结合用更低的延迟访问主机内存。不过这些都是后话。就目前而言HMB是一个成熟的、经过市场验证的折中方案。它不完美但在成本敏感的场景下它让无DRAM SSD从“不能用”变成了“够用”。这个价值是实实在在的。我个人在实际操作中的体会是HMB方案适合那些“预算有限、负载不重、对随机性能有一定要求”的场景。如果你符合这个画像买一块口碑好的无DRAM SSD把省下的钱加到容量上是一个理性的选择。但如果你对性能稳定性有要求或者工作负载比较重那还是老老实实上有DRAM的盘。SSD这东西一分钱一分货省下的成本总会在某个地方找回来。