本期检索说明

先读取 content/collections/deep-radar 截至 2026-09-16 的全部原文链接,并按 URL、标题与实现机制去重。最近 24 小时内,Zig 与 Linux 没有出现同时具备量化实验、源码证据和机制闭环的新材料;Kotlin 的新 PR 以 API、构建与正确性修改为主,Rust 的并行前端默认开关也没有在本次变更中提交新的 benchmark。为避免连续多期偏向 Java,本期优先检查了这些领域,但最终仍以质量红线为先,只收录两个 OpenJDK 一手补丁。

第一项是 RISC-V CRC32 标量 Zbc 折叠:补丁给出完整 MacroAssembler、跨阈值正确性测试和 8B–2MB 吞吐矩阵。第二项是 Shenandoah HdrSeq 直方图重构:补丁给出桶映射源码、DaCapo pmd 的 Native Memory Tracking 数据和百分位测试。两项都仍未合入;后者还是 Draft,本文分析公开实验,不把它们写成已经发布的 JDK 能力。

主题 原始发布日期 一手来源与交叉验证 截稿状态 推荐强度
RISC-V Zbc 标量 CRC32 折叠 2026-09-16 17:38(中原标准时间) OpenJDK PR #32899 / JDK-8392466 / Webrev / jtreg Open,待两名 reviewer,尚未合入 必读
Shenandoah HdrSeq 二进制直方图 2026-09-17 04:46(中原标准时间) OpenJDK PR #32911 / JDK-8392001 / NMT / gtest Draft,尚未评审或合入 推荐

01 · RISC-V:用四条无进位乘法流水折叠 16 字节 CRC32

原文与日期: Chen Qun,2026-09-16 17:38(中原标准时间);OpenJDK PR #32899JDK-8392466Webrev 00。截稿时补丁修改 5 个文件,增加 323 行、删除 14 行,尚未正式合入。

为什么值得读: HotSpot 的 RISC-V CRC32 intrinsic 原本有两条批量路径:普通标量处理依赖查表,支持 RVV 时则进入向量路径;只有标量 Zbc、没有 RVV 的处理器无法利用 clmul/clmulh。这份补丁展示了如何把 x86 PCLMULQDQ 中常见的多项式折叠算法移到 RISC-V 标量指令,同时处理长度阈值、对齐、尾部、特性分派与压缩指令关闭时的远跳转。

核心技术结论: CRC 的数学本质是在 GF(2) 上做多项式除法。无进位乘法把普通乘法里的“加法”换成异或,因此 clmulclmulh 可以一次生成两个 64 位乘积半部。新函数 kernel_crc32_zbc_fold() 每轮读取 16 字节,把上一轮的 128 位状态分别与两个折叠常数相乘并异或,再混入下一块输入:

ASM
clmul   lo_x, x, k1
clmul   lo_y, y, k2
xor     x, lo_x, lo_y
clmulh  hi_x, x_old, k1
clmulh  hi_y, y, k2
xor     y, hi_x, hi_y

常数 0x00000001751997d00x00000000ccaa009e 来自 gzip/CRC32 的反射多项式 0xEDB88320,与 x86 的 fold_128bit_crc32() 及现有 RISC-V/AArch64 carry-less CRC 表一致。它们不能用于 CRC32C;Castagnoli 多项式有独立常数与路径。

循环结束后,两个寄存器仍是 128 位折叠状态。实现没有再造一套 reduction,而是恢复三张 CRC 子表指针,并四次复用现有 update_word_crc32(),把 128 位归约成最终 32 位 CRC。输入先对齐到 8 字节;不足 16 字节的尾部继续交给原有 by4/by1 查表循环。这种“新 fast path 只负责收益最大的中段、复用成熟首尾代码”的拆分,比复制完整 CRC 实现更容易验证。

分派顺序也很关键:有 RVV 时,大输入仍优先走向量路径;否则 UseZbc 且长度至少 128 字节才跳入标量折叠。128B 是实测中折叠首次战胜按 word 查表的交叉点。跳转显式使用 far branch,因为关闭 RVC 后周围指令膨胀,普通短分支可能超出编码范围。

最有价值的实验、源码、benchmark 与汇编细节: 测试平台为 8 核 riscv64 开发板,具备 Zba、Zbc、RVV、Zvbc;用 taskset 固定单核,并以 -XX:+UseZbc -XX:-UseRVV -XX:-UseZvbc 强制标量路径。相对关闭 UseCRC32Intrinsics 的 Java fallback:

输入 Java fallback 启用 intrinsic 提升
256B 394.0 MB/s 2,683.2 MB/s 6.8×
1KB 889.3 MB/s 4,906.6 MB/s 5.5×
16KB 1,352.8 MB/s 6,607.5 MB/s 4.9×
1MB 1,057.4 MB/s 6,179.6 MB/s 5.8×
2MB 1,040.1 MB/s 6,175.9 MB/s 5.9×

大块数据稳定在约 6.2GB/s,而 Java fallback 在缓存压力增大后从约 1.4GB/s 下滑到约 1.0GB/s。需要准确区分“整个 intrinsic”与“本次新增路径”:表中 8B 的 12.3×、64B 的 3.8×都低于 128B 阈值,实际仍走已有按 word 查表代码,不能归因于新 Zbc 折叠;能直接证明新路径收益的是 256B 以上的数据。

新增 TestCRC32RiscvZbc 会按 CPU 特性启动三种子 VM:纯 Zbc、Zbc+RVV,以及关闭 RVC 的 Zbc+RVV。测试覆盖偏移 {0,1,2,3,4,5,7},长度跨过 128B 分派点和每个 16B 循环边界,并同时检查 byte array 与 direct ByteBuffer;参考值由独立逐 bit Java 实现生成。两个实板分别覆盖“Zbc 无 RVV”与“Zbc+RVV+Zvbc”,避免只在开发板上关闭 flag、却从未验证真正无向量硬件。

适合的工程师背景: 熟悉 HotSpot intrinsic、RISC-V Zbc/RVV、CRC 多项式或压缩/网络数据路径,希望理解标量 carry-less multiply 如何替代查表循环的 JVM 与底层性能工程师。

预计阅读收益: 约 60–90 分钟;可以掌握 128 位 CRC folding 的寄存器数据流、CPU 特性分派和阈值选择,并学会区分“启用整个 intrinsic 的收益”与“新增 fast path 的边际收益”。

02 · Shenandoah:用二进制指数缩窄直方图,而不是牺牲百分位精度

原文与日期: Paolo Fontanilla,2026-09-17 04:46(中原标准时间);OpenJDK PR #32911JDK-8392001。截稿时补丁修改 3 个文件,增加 20 行、删除 22 行,仍为 Draft。

为什么值得读: Shenandoah 用 HdrSeq 累积各 GC phase 的大量耗时样本,再计算百分位。原实现不是保存每个样本,而是按数量级建立二维直方图;问题在于它为每个十进制 decade 分配 512 个 sub-bucket,精度远高于实际日志所需。补丁没有简单把 512 改小,而是改变归一化基数,使更少的桶仍保持接近的相对误差。

核心技术结论: 旧结构是 24 个十进制 magnitude bucket × 512 个 value bucket,共 12,288 个计数槽。它通过循环除以或乘以 10,把正数归一化到约 [0.1, 1),再以 v * 512 定位 sub-bucket。新结构改为 48 × 64,共 3,072 个计数槽,数量缩小 4 倍:

C++
ValBuckets = 64;
MagBuckets = 48;
MagMinimum = -32;

v = std::frexp(val, &exponent);  // v ∈ [0.5, 1)
bucket = exponent - MagMinimum;
sub_bucket = (int)((v - 0.5) * 2.0 * ValBuckets);

frexp 把值拆成 v × 2^exponent。虽然每个二进制区间只有 64 个子桶,但一个区间仅覆盖 2 倍范围;旧十进制区间覆盖 10 倍范围。新桶在 v=0.5 附近的最坏相对宽度约 1.56%,到区间高端约 0.78%;旧桶在 v=0.1 附近约 1.95%,高端约 0.2%。它牺牲了一部分高端过剩精度,却没有让最差相对分辨率变差。

百分位反解由 pow(10, magnitude) 改成 std::ldexp:先把 sub-bucket 位置映回 [0.5,1),再乘 2^exponent。零没有可表示的二进制 magnitude,因此被饱和到最小桶;对应 gtest 期望值从精确 0 改为 2^-33 ≈ 1.1641532182693481e-10。这是本方案明确的语义变化,虽然对 GC phase 时间统计可忽略,却不应在摘要中隐藏。

最有价值的实验、源码与 benchmark 细节: 作者在 DaCapo pmd 上用 Native Memory Tracking 比较两类分配。magnitude 指针层由 56,448B 增至 112,896B,因为 bucket 数从 24 翻倍到 48;真正占大头的 sub-bucket 数据由 448,512B 降至 90,368B,下降 79.85%。两者合计:

TEXT
Before:  56,448 + 448,512 = 504,960 B
After:  112,896 + 90,368 = 203,264 B
Change: -301,696 B(-59.75%)

这组数据说明“顶层元数据增加、总体仍显著下降”,比只引用约 0.504M → 0.203M 更能解释结构权衡。补丁同时运行 hotspot_gc_shenandoahtest_shenandoahNumberSeq.cpp 与内部 CI,并比较 GC 日志;但公开性能证据只有一个 DaCapo 工作负载,没有给出 GC pause、吞吐或 CPU 成本矩阵。特别是 frexp/ldexp 替代简单循环后的运行成本尚未量化,因此合理结论仅是“显著降低 HdrSeq 内存并维持测试中的百分位行为”,不是“Shenandoah 整体性能提升 59.7%”。

适合的工程师背景: 维护 Shenandoah/HotSpot GC 可观测性、HDR histogram、延迟分位数或需要压缩大范围浮点统计结构的运行时工程师。

预计阅读收益: 约 40–60 分钟;可以理解基数、动态范围、sub-bucket 数与相对误差之间的关系,并学会从 NMT 调用栈拆分元数据和主体数组,而不是只看一个总内存数字。

中国大陆 ToC 硬件价格观察

数据口径

窗口为 2026-08-19 至 2026-09-17,单位人民币,六类硬件继续固定同一 SKU。9 月 17 日复核时,9800X3D 页面明确显示京东最低 ¥2,619,因此新增一个真实 CPU 采样点;GPU、主板、DRAM 与 HDD 页面未取得可读报价,SSD 页面请求超时,均不复制旧值冒充今日行情。折线尾部的空白表示证据缺失,不代表价格横盘。

中国大陆六类 PC 硬件公开价格事件

类别 固定样本与最后可复核价 30 日窗口内真实走势 建议
CPU Ryzen 7 9800X3D,9/17 京东最低 ¥2,619 8/21 ¥2,609 → 9/9 ¥2,449 → 9/14 ¥2,639 → 9/15、9/17 ¥2,619 观望;反弹后连续两个真实点停在 ¥2,619,仍比窗口低点高 6.94%
GPU MSI RTX 5070 VENTUS 3X 12G,最后可核验 9/13 ¥4,464.34 8/29–9/13 六个真实点均为 ¥4,464.34,之后缺少新点 继续观望;数据已间隔 4 天,付款前重新核验渠道与保修
主板 ASUS TUF B850M-PLUS WIFI7,最后可核验 9/8 ¥1,299 8/31 ¥1,449 → 9/2–9/8 ¥1,299 刚需可关注 ¥1,299;确认 WIFI7 版本、供电与售后
DRAM Kingston FURY Beast DDR5-6000 32GB,最后可核验 9/9 ¥3,900 9/2 ¥3,900 → 9/5 ¥3,860 → 9/6–9/9 ¥3,900 观望;没有连续下跌证据,且最后报价已超过一周
HDD IronWolf Pro 8TB ST8000NE001,最后可核验 9/10 ¥1,849 9/1–9/10 五个真实点均为 ¥1,849 按容量刚需购买;优先比较五年保修和数据恢复服务
SSD ZHITAI Ti600 2TB,最后可核验 9/10 页面最低 ¥749 9/2 ¥1,919 → 9/5–9/10 ¥749;同页渠道价差异常大 仅在确认 2TB 规格、颗粒、商家与保修后考虑

价格来源: 9800X3DMSI RTX 5070 VENTUS 3XASUS TUF B850M-PLUS WIFI7Kingston FURY DDR5-6000 32GBIronWolf Pro 8TBZHITAI Ti600 2TB

判断依据

CPU 的今日同口径报价确认 9 月 15 日的 ¥2,619 不是单次页面噪声,但它也没有回到 9 月 9 日 ¥2,449 的窗口低点,因此建议仍是观望而非追价。其余五类缺少今日事实,不更新涨跌结论。SSD 的 ¥749 继续只视为聚合页中的异常低价事件,不能外推为整个 2TB SSD 市场的趋势。

其它你可能关心的

本期结论

两项优化都在重新设计“范围如何被分段”。CRC32 把字节流按 16B 折叠,用硬件多项式乘法减少逐项查表;HdrSeq 把十进制大区间换成二进制窄区间,用更少的子桶保持相近的相对分辨率。可迁移的工程方法也一致:先找到数据规模跨过固定开销的阈值,再用边界测试和分项测量证明优化没有把成本或误差悄悄搬到别处。