slime/research/experiments/full_search_feasibility/REPORT.md

8.9 KiB
Raw Blame History

实验结论:定点求解显著提速,全世界目录仍不适合启动

日期:2026-10-11,Asia/Hong_Kong。硬件:RTX 3060 Laptop、Ryzen 7 5800H,WSL,CUDA 12.0。

结论

  1. 保留输出差过滤+逐格区间求交。 GPU 搜索 kernel 在三组同任务对照中快 197~292 倍,完整输出一致。
  2. 保留低位坐标类复用。 52,213 个实际位置的完整低位根列表与 32 个代表类一致;它减少根生成,不能消除后续中间位枚举。
  3. 否决低位位表查找替换。 此 GPU 上查表比直接整数计算多耗时约 36%。
  4. 保留按首个奇数格逆推拒绝尾部。 相比逐格枚举全部尾部,128 坐标批次快约 24 倍,并覆盖多次拒绝和多个格子首次拒绝的情况。
  5. 当前路线仍不足以生成全世界全部种子的目录。 随机批次吞吐外推:首次输出分支约 0.9 年;包含拒绝重抽的完整分支约 16 年。这里已乐观地摊薄进程启动、复用低位根生成,不是实际跑完全世界,也不是所有可能算法的下界。

代码是独立实验,没有替换原来的正式入口。

GPU 求解器对照

全部模式处理相同的 lower35 候选,完整预热后轮换顺序测量五轮,核对排序后的完整 (world_seed,x,z) 列表。

负载 lower35 数 原排序事件求解器 仅区间求交 输出差+原求解器 输出差+区间求交 最佳相对原版
已知位置 (51069,419124) 11,010,048 63.750 ms 0.763 ms 0.390 ms 0.324 ms 197.0×
21 个压力/边界坐标 62,128,128 363.876 ms 4.674 ms 1.757 ms 1.245 ms 292.2×
4096 个均匀随机坐标 387,973,120 2318.625 ms 29.380 ms 12.297 ms 8.157 ms 284.2×
65536 个均匀随机坐标 5,944,901,632 未重测 407.659 ms 175.974 ms 131.670 ms —

以上均为 CUDA event kernel 中位数,不包括低位根生成、CUDA 初始化、分配和传输。21 坐标组包含已知命中附近位置、原点、世界边界和 int32 边界;它不代表随机平均坐标。

已知位置和压力组均得到相同的 24 个种子。两个随机组没有命中。随机无命中不单独构成正确性证据,另有下面的独立校验。

主要收益来自更早排除不可能共同满足模 10 条件的候选:

delta_i = (q_i(0) - q_0(0)) mod 2^31
必要条件:delta_i mod 10 属于 {0,8}

原因是改变高 13 位,对所有输出施加相同的模 2^31 平移;两个最终输出都是 10 的倍数时,差模 2^31 只能具有上述余数。多数候选在几个格子后就失败,不再支付 25 格的事件排序成本。差过滤通过后,最多两个“区间+余数”做逐格求交,再完整 Java 验证。

根分布与全局工作量

确定性均匀随机抽样 65536 个锚点,两轴范围 [-1875000,1874999]:

指标 结果
首次输出低位无根比例 96.9162%
低 18 位根总数 45,356
每坐标平均根数 0.69208
平均数的正态近似 95% 区间 0.61054~0.77361
最大根数 1015

分布有较长尾部。置信区间只说明该抽样模型中的根数均值不确定性,不包含 GPU 频率、长期运行、分组调度及模型覆盖的误差。

按样本均值,世界的 14,062,500,000,000 个锚点仍约有:

14,062,500,000,000 × 0.69207763671875 × 131072
= 1.2756375 × 10^18 个 lower35 候选

新 kernel 在 65536 坐标批次中约处理 451.5 亿个 lower35/秒。把实测批次吞吐线性扩展到全部锚点,首次输出分支约 0.895 年。这已不适合用早先的“已知命中坐标耗时 × 所有坐标”去估计成几万年,但距离几周完成仍有明显差距。

坐标类复用和位表查找

归一化有效种子 s=world_seed+T(x,z) 后,图案相对坐标项的低 18 位在 X 上以 65536、Z 上以 131072 为周期。

选取 32 个有根的类,并展开成世界内全部 52,213 个实际锚点。程序逐一比较每个同类位置的完整归一化低位根列表,全部一致。

低位筛选负载 直接整数计算 32 KiB 位表查找
65536 随机坐标 280.639 ms 380.533 ms
32 个类代表 0.138 ms 0.209 ms
52,213 个实际位置重复计算 293.866 ms 409.952 ms

因此查表方案不保留。类复用在算法上成立,表中只比较筛选 kernel,未把归类、展开和传输成本当作零成本的实测完整方案。全世界最多 2^33 个类,按大批次根筛选吞吐粗略外推,代表类筛选约 10.2 小时;更高位求解仍须处理具体坐标,不能再乘一个“1637 倍”全流程加速。

首次输出无根并不排除拒绝重抽解,所以不能据此跳过完整语义的异常分支。

完整覆盖拒绝重抽

朴素补扫对 25 格分别枚举 8 × 2^17 个首次拒绝状态,共 26,214,400 个候选/坐标。

本轮新增的规范化补扫只枚举一次有效种子的低 18 位 p:

  1. 从 p 算出每格首次输出的奇偶。
  2. 若存在奇数格,选第一个。任何真实解必须在这一格首次拒绝,否则不可能返回 0。
  3. 该格状态的低 18 位已确定,在拒绝区间中恰好有四个完整推进后状态与它一致;逆推这四个完整种子,执行全部格子的精确 Java 检查。
  4. 若全部格子都是偶数,则为每一格补扫四个拒绝状态。

若一个坐标有 R 个全偶低位根,最多生成 2^20 + 96R 个补扫候选。无需假设“多个格子同时拒绝不可能”;选择首个奇数格的必要性对这种情况也成立。所有首次输出都被接受的真实解由普通分支覆盖,任何首次拒绝的真实解由补扫覆盖。最终并集去重。

对照任务 逐格朴素补扫 规范化补扫 去重命中数
已知坐标的单格约束 0.032 ms 0.026 ms 104,848
同坐标前两格约束 0.065 ms 0.053 ms 20,888
同坐标前五格约束 0.139 ms 0.084 ms 109
128 坐标的完整 5×5 93.597 ms 3.908 ms 0

两种补扫逐项比较完整去重列表,单格、多格的非空结果也一致。

同批完整流程:最终成本判断

在同一个 65536 随机坐标批次中,普通分支和规范化拒绝补扫顺序执行,合并、排序、去重;完整预热后测五轮:

区域 中位数
一次低位根准备 kernel 296.573 ms(单次)
普通搜索 kernel 129.157 ms
完整拒绝补扫 kernel 2283.082 ms
两个 kernel 的每轮耗时之和 2413.373 ms
同步、回传、合并在内的 host scan 2356.676 ms

另在 21 坐标压力组完成同样的完整流程,全部 24 个已知结果保留,无额外拒绝解;完整结果已与此前普通分支核对。

本环境观察到 CUDA event 累计时间比 host wall time 高约 2.4%;两种时钟口径分别保留,不用它们混合计算局部加速比。这一差异的原因未单独确定,长期外推只按数量级解释。

按同批完整测量,外推全世界为 16.0~16.4 年。这里不重复支付进程启动,低位筛选可按坐标类摊薄;尚未计入全世界调度、建表、长期频率波动和输出持久化等工程成本。不能宣称已实现完整世界扫描。

补扫约占计算时间的 95%。即使完全删掉这个正确性成本,普通分支仍约需一年。 因此结论不依赖于罕见分支是否必须支持:这轮优化值得用于定点反查和有限批次,但仍不应启动全世界目录生成。

正确性检查与复现

  • CPU 独立直接枚举 4096 个高位平面,共 33,554,432 个完整种子,覆盖 1~25 格约束、随机坐标和已知命中平面。原求解器、区间求解器和输出差过滤版本的完整列表一致。
  • 用单独的 Java 算术实现核对全部 1,048,576 个单格拒绝状态及逆推;其中存在 52,422 个首次输出为奇数、重抽后成功的例子,防止测试只覆盖空结果。
  • CPU 核对 250,000 个格子的坐标周期;GPU 每批抽取最多 64 个坐标完整核对低位根表,并对所有重复坐标类比较完整根列表。
  • GPU 四种求解器、两种根筛选、两种拒绝补扫分别完整核对结果,容量溢出会失败。
  • GPU 与桌面共享,五轮原始数据、温度、驱动、源码哈希及每项命令保存在结果文件。早期对照和后补完整流程的源码哈希分别记录,计算 kernel 的算法一致。
python3 research/experiments/full_search_feasibility/run.py
# GPU 需可访问;无 GPU 时可单独编译运行 cpu_verify.cpp。
python3 research/experiments/full_search_feasibility/run.py --analyse-only

核心代码:interval_solver.hpp、cuda_bench.cu。 汇总:results/summary.json。完整实验数据:results/all.json。