review(follow-ups): 落地上轮建议并给出实测结论(#2/#4 回退、#3 不重写)
一、Tools 完善 * OffscreenChecks `edgestats`:改为自动挑"最有起伏"的信号。旧实现固定取 `signals[0]`,而 MF4 的第一条信号是常量(6000)⇒ 三个阈值的断言退化成 "0 == 0" 的空转。现在扫描前 200 条挑 `max-min` 最大者,SCATTER_TEST 上 三个阈值分别得到 (20,19)/(20,19)/(20,19),与独立参考实现逐位相同。 * UnitTests 新增 `stdio_mingw_vs_ucrt_formats`:把 MinGW ANSI stdio 与系统 UCRT 的 printf 在**本程序实际用到的全部格式**(`%.*f` / `%.6g` / `%g` / `%.4e` / `%.2f %ls` / `%llu` / `%lld` / `%02X` / `%.2f%%`)上做逐字符比对, 13.6 万次调用 **0 处差异**(覆盖 1e-40~1e40)。它是"把 swprintf 让给 UCRT" 这条体积优化的验收标准。 * Tools/README.md:同步新增用例与断言数量(219 项 / 18 用例)。 二、第 33 轮报告 §10 后续建议的结论(详细数字见 Progress 第 34 轮) 1. **`EdgeScanFor` 状态查找哈希化:实测后回退。** 实现方式为 `deque` + `unordered_multimap<keyHash, EdgeScanState*>`(桶内仍 逐字段比对,碰撞安全;新建/淘汰/定向作废/清空四处同步索引),功能与像素 验证全绿。但 198 个状态的整轮查询只从 0.097 降到 0.073 us/query(一轮省 ≈4.8 us),而产物体积 +5,632 B。⇒ 回退。 同时修正报告的量级:原估"288 信号 ≈0.3ms/帧",实测 ≈20us/帧。 2. **`EdgePanelLayoutFor` 表驱动化:不做。** 实测 1.9~2.5 us/次(每帧约 14 次 ≈30us),不是热点;第 33 轮已消除"按种类分派"的重复,剩余 957 行是几何算式 本身,无法表驱动。本轮改为交付"让这类重写可验证"的手段: `-run panels -mode record/compare` 逐面板比对几何 + 像素哈希。 3. **`wcstod` 自写替身:实测 0 字节收益。** 只加 `-D__USE_MINGW_ANSI_STDIO=0` 全量重编后产物仍是 788,480 B、`mingw_wpformat.o` 仍被链接。原因是预编译 libstdc++ 自己引用 `__mingw_swprintf`:只要还调用 `std::to_wstring` / `std::to_string`(全仓约 80 处,若干处实参是浮点), gdtoa 必然被链入。⇒ 回退,并在 Makefile 留下说明防止重复尝试。 三、文档 * `Documents/Code_Review_Plan.md` 新增 §六(第 34 轮节点与验收标准)。 * `Documents/Code_Review_Progress.md` 新增第 34 轮逐节点记录(含全部实测数字)。 * `Documents/Code_Review_Report.md` 新增 §11(结论表 + 两处量级修正 + 更新的后续建议)。 * `Documents/agent_mem.md` 新增第 34 轮规则:Tools 约定、两个构建陷阱、 两条"别再重复做"的实验结论。 验证: * `make release`(删 .o 全量)零 error / 零 warning,产物 **788,480 B**(与改动前一致)。 * `make -C Tools` 零 error / 零 warning。 * `UnitTests.exe` → checks=219 failed=0 cases=18。 * `OffscreenChecks.exe -all` → 5/5 检查 PASS,checks=71 failed=0。
This commit is contained in:
1 parent
97e9163314
commit
5c48bf922e
8 files changed
+418
-2
No files matched your search
@@ -145,6 +145,99 @@ Makefile 按目录通配收集源文件,**无需登记新文件**。
|
||||
因此不再拆分。
|
||||
* **性能项**:未发现新的可复现热点;已记录 3 个"还能再快一点"的点(见报告 §6.2)。
|
||||
|
||||
---
|
||||
|
||||
## 第 34 轮(2026-11-04):验证基础设施 + §10 后续建议落地
|
||||
|
||||
### T1 验证工具入库 —— ✅ 完成(提交 `97e9163`)
|
||||
|
||||
**改动**
|
||||
|
||||
1. `.gitignore`:删除整目录忽略的 `Tools/`,改为 `Tools/**/Build/`(只忽略各工具产物)。
|
||||
2. 新增 `Tools/Makefile`:`make` / `make UnitTests` / `make OffscreenChecks` / `make clean` / `make help`;
|
||||
工具链接本体 `../Build/Release/*.o`(排除 `Main.o`),`-MMD -MP` 跟踪头文件依赖。
|
||||
3. 新增 `Tools/UnitTests`(`Inc` + `Src` + `Build`)与 `Tools/OffscreenChecks`(同构)与 `Tools/README.md`。
|
||||
|
||||
**踩到并修掉的两个构建陷阱**
|
||||
|
||||
* 工具源码也加 `-flto` 会让 GCC 15.2.0 在链接阶段 `choose_baseaddr`(i386.cc:7447)**ICE**
|
||||
⇒ 工具源码不带 `-flto`,只在链接参数里带 `-flto -flto-partition=one`。
|
||||
* `$(foreach)` 生成的工具目标早于 `all` 出现 ⇒ make 把**第一个**显式目标当默认目标,
|
||||
直接 `make` 只会构建 `UnitTests` ⇒ 显式 `.DEFAULT_GOAL := all`。
|
||||
|
||||
**实测**:`make -C Tools` 零 warning;两个产物分别在 `Tools/<Tool>/Build/<Tool>.exe`。
|
||||
|
||||
### T2 单元测试 —— ✅ 完成(219 条断言 / 18 个用例)
|
||||
|
||||
覆盖:`TryParseDouble` 与 libc `strtod` **逐位一致**(6 万条随机十进制串)、
|
||||
输入接受性(尾随字符 / 十六进制浮点 / `inf` / `nan`)、`FormatDecimal*` 永不科学计数法、
|
||||
`NiceStep` / `BuildTicks`、公式语法与语义、`FormulaProgram` 与 `EvaluateFormula` 逐位一致、
|
||||
`ApplyDrawTransform` 顺序、`TransformValueRange`、滑动平均多阶等价性、
|
||||
`DataSet::FormulaTransformFor` 值域与分组极值(逐点参考实现比对、命中同指针、样式变化失效)、
|
||||
以及新增的 `stdio_mingw_vs_ucrt_formats`(见 T6)。
|
||||
|
||||
**过程中修正了 5 处"我以为的语义"**(都以源码为准,测试跟着产品改):
|
||||
`9.999999999999999` 属 >15 位有效数字(允许 1 ULP);`1..2` 其实合法;
|
||||
`FormulaIsIdentity` 不去空格;非法公式求值时 `EvaluateFormula` **原样返回采样值**(不是 NaN)。
|
||||
|
||||
### T3 离屏验证 —— ✅ 完成(5 个检查 / 71 条断言)
|
||||
|
||||
* `smoke`:初始化 + 加载 + 渲染 + 落盘;**同一状态两帧逐像素相同**(实测差异 0 像素)。
|
||||
* `frames`:连续帧抓取(PNG + 区域 FNV 哈希 + 耗时),帧序列至少出现一次可见变化。
|
||||
* `panels`:7 个面板全部展开后的几何不变式(必须被绘图区夹住)+ 像素基线 `-mode record/compare`。
|
||||
* `edgestats`:边沿统计与工具内**独立朴素实现**逐位比对(阈值 2.4875/4.975/7.4625 →
|
||||
20/19、20/19、20/19 完全一致;中心轴 1200/1179 也能完成)。
|
||||
* `perf`:整帧中位数、`EdgePanelLayoutFor` 单次、198 个统计状态的整轮查询耗时。
|
||||
|
||||
**全程离屏**:窗口 `SW_HIDE`、"鼠标"用 `Application::HandleMouseMove()` 合成注入、
|
||||
像素从后备缓冲区读取;进程用 `std::_Exit()` 收尾(避免单例析构晚于 `GdiplusShutdown`)。
|
||||
|
||||
### T4 `EdgeScanFor` 状态查找哈希化 —— ⛔ **实测后回退**(建议 #2)
|
||||
|
||||
* **改动前**:`mutable std::vector<EdgeScanState>` + 逐字段线性扫描。
|
||||
* **改法**:容器改 `std::deque`(指针稳定)+ `mutable std::unordered_multimap<uint64_t, EdgeScanState*>`
|
||||
按身份哈希索引,桶内仍逐字段比对(碰撞安全);新建 / 淘汰 / 定向作废 / 清空四处同步索引。
|
||||
* **正确性**:`edgestats` 全绿(真实数据的计数与独立参考实现逐位相同),`panels` 像素基线不变。
|
||||
* **性能(198 个状态,`MF4-Record.MF4`)**:整轮查询 `0.097 → 0.073 us/query`
|
||||
(一轮 198 次查询省 ≈4.8 μs)。
|
||||
* **体积代价**:`788,480 → 794,112 B`(**+5,632 B**)。
|
||||
* **结论:回退**。5.6 KB 的体积换 ≈5 μs/帧(约占 5 ms 整帧的 0.1%)不成立 ——
|
||||
这与 §6.2 原本的判断一致,本轮把它从"估计"变成了**实测**。
|
||||
⚠️ 同时修正了 §6.2 的量级:报告原估"288 信号时 ≈0.3 ms/帧",实测 198 状态整轮 **≈20 μs/帧**,
|
||||
差一个数量级(线性扫描的常数很小)。
|
||||
|
||||
### T5 `EdgePanelLayoutFor` 表驱动化 —— ⏸ 只交付"可验证手段",**未重写**
|
||||
|
||||
* 第 33 轮已把**按种类分派**收敛成唯一派发点(`LanePanelEnabled` / `LanePanelStateOf` /
|
||||
`LanePanelScrollOf`,且 `switch` 不写 `default:` 让 `-Wswitch` 兜底)。
|
||||
* 剩余的重复是 957 行**几何算式本身**(每个面板的内容行高、表头、按钮、滚动区各不相同),
|
||||
无法用"每面板一行元数据"表达。
|
||||
* 本轮实测该函数 **1.9~2.5 μs/次**(2000 轮 × 7 种),按每帧约 14 次调用计约 **30 μs/帧**,
|
||||
不是热点。
|
||||
* ⇒ 重写的收益是"可读性",代价是 957 行几何公式的可回归风险。
|
||||
**本轮交付的是让这类重写变得可验证的工具**:`-run panels -mode record/compare`
|
||||
会逐面板比对**几何 + 像素哈希**(7 个面板、含内容区/滚动条/按钮)。
|
||||
|
||||
### T6 `wcstod` 自写替身(省 gdtoa)—— ⛔ **实测 0 字节收益**(建议 #4)
|
||||
|
||||
* 报告 §1.3 的估计是"≈20 KB"。本轮先做**最小实验**而不是先写代码:
|
||||
在 `Makefile` 里加 `-D__USE_MINGW_ANSI_STDIO=0`(把 `swprintf` 交给系统 UCRT),全量重编。
|
||||
* **实测:产物仍然 788,480 B,一个字节都没变**;map 里 `mingw_wpformat.o` 依旧被链接。
|
||||
* **原因(用 3 行最小程序确认)**:预编译的 **libstdc++ 自己引用 `__mingw_swprintf`** ——
|
||||
只要工程里还调用 `std::to_wstring` / `std::to_string`(全仓约 80 处,其中若干处实参是浮点),
|
||||
链接器就必须把 MinGW 的 printf 引擎(含 gdtoa)拉进来。
|
||||
* ⇒ 真正的 33 KB 收益要以"替换全部 80 处 `std::to_*string`(含浮点格式语义)"为代价,
|
||||
风险与收益不匹配,**不实施**。该实验已回退,只在 `Makefile` 里留下一段说明防止重复尝试。
|
||||
* **顺带产出可复用的验收测试** `stdio_mingw_vs_ucrt_formats`:
|
||||
同一批真实格式(`%.*f` / `%.6g` / `%g` / `%.4e` / `%.2f %ls` / `%llu` / `%lld` / `%02X` / `%.2f%%`)
|
||||
× 13.6 万次调用做**逐字符比对**,**0 处差异**。将来若真做迁移,这条测试就是验收标准。
|
||||
|
||||
### 本轮验证汇总
|
||||
|
||||
| 项 | 结果 |
|
||||
| --- | --- |
|
||||
| `make release`(删 `.o` 全量) | 零 error、零 warning |
|
||||
| `make -C Tools` | 零 error、零 warning |
|
||||
| `Tools/UnitTests/Build/UnitTests.exe` | `checks=219 failed=0 cases=18` |
|
||||
| `Tools/OffscreenChecks/Build/OffscreenChecks.exe -all` | 5 个检查全 PASS,`checks=71 failed=0` |
|
||||
| Release 产物 | **788,480 B**(与第 33 轮末一致;T4/T6 均回退) |
|
||||
Reference in new issue
Block a user