# 普通搜索:坐标类复用及只展开有根类 2026-10-11(Asia/Hong_Kong);RTX 3060 Laptop GPU。接续 [16 候选成组筛选实验](REPORT.md)。补扫未修改、未运行。 结论:复用已接入可执行实验流程,计入分组、根生成、候选展开、必要传输、搜索和结果回传后仍有效。收益取决于同批坐标类重复率及有根类比例,不是统一倍数。对几乎无重复类的散点,直接成组筛选更快。 ## 四条路径 - 模式 0:每个位置生成根,旧差过滤+区间求交。 - 模式 1:每个位置生成根,上一轮 16 候选成组筛选。 - 模式 2:坐标按 `(x mod 65536,z mod 131072)` 分类,每类生成一次根,再在 GPU 上展开任务,成组筛选。 - 模式 3:先分类、只构造代表位置;筛出类根后,仅构造和上传有根类的具体位置,再展开任务,成组筛选。 四条路径都重算本轮的类根,没有拿前一轮缓存假装免费。模式 2/3 使用各类排序后的完整根列表和位置偏移,在 GPU 上生成 `(具体位置,root)` 任务。模式 3 压缩位置后,将结果还原到原始输入索引。 程序检查根缓冲区和命中缓冲区容量,超限明确失败,不截断。单批支持最多 65,536 个位置、4,194,304 个展开后的根任务;较大任务仍需外层分批。当前是批次级调度实验,不是已经具备全世界断点续跑能力的正式扫描器。 ## 实测批次耗时 预热一次、三轮轮换模式顺序。下表为 CPU 单调时钟测量的批次耗时中位数,单位 ms。 | 输入 | 位置数 / 类数 | 模式 0 | 模式 1 | 模式 2 | 模式 3 | |---|---:|---:|---:|---:|---:| | 已知位置所属类的全部世界内位置 | 1653 / 1 | 364.023 | 62.016 | 55.373 | 56.867 | | 32 个有根类的全部世界内位置 | 52213 / 32 | 4691.311 | 915.446 | 656.710 | 676.742 | | 512 个随机类,每类抽 64 个世界内位置 | 32768 / 512 | 172.222 | 141.138 | 14.235 | 9.586 | | 4096 个均匀随机散点 | 4096 / 4096 | 24.022 | 17.902 | 19.239 | 19.502 | **计入**:本批次位置项构造、分类、代表类筛根、类根回传/整理、偏移构造、必要 H2D 传输、GPU 根任务展开、每根公共项预计算、搜索、命中回传及排序、模式 3 结果索引还原。 **不计入**:输入文件读取、一次性 CUDA 初始化/工作区申请、专用于对照验证的完整任务回传和排序、日志打印。一次性准备另记为 `setup_ms`,这四批约 217~242 ms。预热复用了显存;新增预计算仍每轮执行。这里是长期运行时可摊薄初始化后的批次耗时,不是启动一次命令的进程总耗时。 本轮直接使用 host 时间,不与前一轮的 CUDA event 时间混算。 ## 收益在哪里 以随机 512 类批次为例: - 原先要为 32,768 个位置重复筛根;现在仅筛 512 个代表。 - 其中 19 个类有根,只有 1,216 个具体位置需要构造坐标项并传入后续搜索。 - 展开后的完整任务仍是相同的 15,424 个 `(位置,root)`,没有省略任何普通分支候选。 - 模式 3 的阶段中位数:初始分类/代表构造约 0.416 ms,类根生成约 2.049 ms,整理/展开约 0.690 ms,搜索及回传约 6.775 ms。各阶段中位数不必精确相加等于总耗时中位数。 - 相比上一轮成组筛选流程,本批再加速 14.72×;相对模式 0 为 17.97×。 32 个有根类的压力批次有 1,693,228 个根任务,全部类都必须展开,计算主要花在后续搜索。模式 3 相对模式 1 仅加速 1.35×;模式 2 略优,因为无需压缩位置和还原索引。 随机散点没有类复用收益,分类、回传和整理增加开销;模式 3 比模式 1 多耗时约 8.9%。因此应按类组织大范围遍历;不能对任意散点输入无条件启用该流程。 ## 正确性和边界检查 每一轮、每一种模式均将**全部展开根任务列表**排序后与模式 0 逐项比较,并比较完整命中列表,不只是比较数量。 - 四批完整根列表和命中列表全部一致。 - 已知类批次保留原有 24 个命中,其他三批无命中。 - 全无根类的全部世界内位置:四条路径都生成 0 个任务、0 个命中;模式 3 正确处理没有具体位置可展开的情况。 - 原 21 个压力/边界位置:覆盖原点、世界边界和 int32 边界,四条路径相同的 24 个命中。 - 随机打乱 32,768 个混合位置的输入顺序:完整根和结果列表依然一致,位置压缩/还原不依赖同类位置连续排列。 原始记录在 `pipeline_results/*.jsonl`,汇总、源码哈希在 `pipeline_results/summary.json`;补充检查在 `pipeline_results/edge_validation.json`。 ## 对全世界估算的影响 本轮证明此前“复用低位根”的前提可以落地,且筛类后只展开有根位置能控制部分开销。但不能把本轮 14.72× 再乘到此前约 50 天的估算上:此前约 50 天已经假定根充分复用,主要计算的是后续搜索。 本轮仅抽取 512 个随机类,根分布样本不足以重新估计全世界平均耗时;32 个有根类更是有意选择的压力集。维持此前约 50 天作为普通搜索阶段的乐观吞吐量级,不将其升级为完整全世界工期承诺。 下一步若继续研究算法,应优先减少剩余中间位组的筛选工作,或研究不同实际位置之间能否共享更高位的必要条件。当前低位根复用只消除了根生成重复,不能推导出高位结果也相同。 ## 复现 ``` python3 research/experiments/normal_search/run_pipeline.py python3 research/experiments/normal_search/verify_pipeline_edges.py ``` 两个脚本都会编译 GPU 基准程序。需要 NVIDIA GPU、nvcc 和 g++ 环境。实现入口为 `pipeline_bench.cu`,复用上一轮 `cuda_bench.cu` 中的内核。原正式入口未替换。