geopro/docs/superpowers/plans/poc-results-B.md

180 lines
8.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# POC-B 实测结果gpr_poc headless 度量)
工具:`tools/gpr_poc`CLI构建产物 `build/release/tools/gpr_poc/gpr_poc.exe`
执行机Windows 11MSVCVS18 Community+ NinjaRelease/O2
日期2026-06-23。
整条地基链路:
`assembleGprSurvey → buildGprVolume → ChunkedVolumeStore::write → buildPyramid → WholeVolumeSource(load)`
---
## 1. selftest合成极小数据—— PASS
命令:`gpr_poc selftest`
- 构造 2 通道合成 surveysamples=8traces=12写临时 `.iprb/.iprh/.ord`
走完整 `assembleGprSurvey → buildGprVolume → write(brick=4) → buildPyramid(1) → WholeVolumeSource`
- 断言ntraces/samples/channels、channelY 升序、GridSpec `2x2x8`、建体维度、
金字塔层数==2、整卷维度一致、(0,0,0) 非 blank。
- 结果:**PASS**(退出码 0
结论:除真实 `.iprb` 读入外,**整条地基管线在合成数据上端到端跑通**
(装配几何、建体量化、分块压缩落盘、金字塔降采样、整卷重组加载均正确)。
---
## 2. 真实数据D:\Downloads\明星路,线 001—— **PASS实测**
> 更新(任务 9b2026-06-23先前 BLOCKED 的根因(`readIprb` 硬假设
> `traces = lastTrace + 1`)已修复。`readIprb` 改为**以文件大小为权威**
> `traces = fileBytes / (samples·2)`),真实数据装配通过。
命令:
```
gpr_poc build "D:\Downloads\明星路" --line 001 --cellXY 0.2 --cellZ 0.05 --out <store> --levels 2
gpr_poc load <store>
```
### 根因回顾off-by-onelastTrace+1 vs 真实道数)
`readIprb` 硬编码 `traces = h.lastTrace + 1` 并对文件字节做严格相等校验。
真实明星路每个通道文件恰好含 `lastTrace` 条道(少 1 道),逐通道实测:
| 通道 | 文件字节 | samples | LAST TRACE | 旧期望(=samples·(lastTrace+1)·2) | 实际道数(=bytes/(samples·2)) |
|------|----------|---------|------------|----------------------------------|------------------------------|
| A01 | 74390810 | 821 | 45305 | 74392452 | 45305 |
| A02 | 74394094 | 821 | 45307 | 74395736 | 45307 |
| A12 | 74392452 | 821 | 45306 | 74394094 | 45306 |
**规律一致**:所有通道「实际道数 == LAST TRACE」。修复后 `readIprb` 不再用 `lastTrace`
决定道数装配按各通道道数最小值对齐min=45305
### build 实测指标line 001, cellXY=0.2, cellZ=0.05, levels=2
| 指标 | 值 |
|------|-----|
| 发现通道数 | 14 |
| 装配后 ntraces / samples / channels | 45305 / 821 / 14 |
| dx / dz | 0.049084 / **0.00977756** |
| GridSpecnx×ny×nz | **11120 × 8 × 162** |
| 体素数 | 14,411,520 |
| 原始体积int16 | 28,823,040 B27.49 MB |
| 落盘 data.bin含金字塔各级 | 15,317,628 B14.61 MB |
| 压缩比(原始/落盘) | **1.88×** |
| 装配耗时 | 12,551 ms |
| 建体耗时 | 1,926 ms |
| 落盘耗时 | 3,597 ms |
| 金字塔耗时 | 3,923 ms |
| build 端到端墙钟 | ≈22.6 s |
| 峰值内存 | **4,975 MB** |
### load 实测指标
| 指标 | 值 |
|------|-----|
| 加载耗时 | 335 ms |
| 整卷维度 | 11120 × 8 × 162 |
| 整卷字节 | 28,823,040 B27.49 MB |
| 峰值内存 | 38 MB |
无 OOM、无超时未调粗 cellXY 即一次通过。
### 峰值内存说明4.98 GB
峰值由**装配阶段**主导:同时持有 14 通道 BScan14×74 MB ≈ 1 GB int16
+ `GprSurvey.values`**double**14×45305×821×8 B ≈ 4.2 GB
建体/落盘/加载本身很轻load 仅 38 MB。若后续要压内存可让 survey.values
改存 int16 或流式装配但当前规模单机可承受POC 不做此优化。
---
## 3. 深度/Z 尺度诊断结论(任务 9b
先前 §3 预估「nz=1、深度量级 8e-6 m」是在 SOIL VELOCITY **未正确换算**时写下的
(当时按 100 m/s 计算。Task 1 已将 `SOIL VELOCITY`(头文件单位 m/µs×1e6 存为 m/s
本任务实测确认整条 Z 链路正确:
-SAMPLES=821TIMEWINDOW=160.352 nsSOIL VELOCITY=100→ 1e8 m/s
- `depthOfSample(820) = 1e8 × 160.352e-9 / 2 ≈ **8.018 m**`(深度跨度合理)。
- `dz = depthOfSample(1) = 8.018/820 ≈ **0.009778 m**`(实测 0.00977756,吻合)。
- 故 cellZ=0.05 下 `nz = ceil(8.018/0.05)+1 = **162**`(实测 162非 1
**结论**`assembler`/`GprGeometry`/CLI `specFromSurvey` 的 Z 计算**全部正确**
无需改 CLI。先前的 nz=1 症状是 soilVelocity 换算缺失时代的遗留,现已不复存在。
CLI 的 `specFromSurvey` 用的是 `survey.dz`(来自 `depthOfSample`),未误用原始 100未漏乘。
---
## 4. 离屏 GPU 渲染基准(任务 9c2026-06-23
工具新增子命令:`gpr_poc offscreen-smoke`(闸门)、`gpr_poc renderB <store> [--frames N]`。
执行机 GPU**NVIDIA GeForce RTX 3060 Laptop GPU**OpenGL 4.5.0 NVIDIA 555.97,硬件加速 True。
### 4.1 闸门offscreen-smoke —— **OK离屏 GL 可用)**
命令:`gpr_poc offscreen-smoke`
- 离屏 `vtkRenderWindow``SetOffScreenRendering(1)`+`SetShowWindow(false)`256×256
→ 加 cube actor → `Render()``GetRGBACharPixelData` 读回。
- 读回 65536 像素,非背景像素 **28224**cube 正确画出)。
- GL vendor=NVIDIA Corporationrenderer=RTX 3060 Laptop GPU硬件加速 True。
- **结论:离屏 GPU 渲染在本机可用**,继续真实基准(非编造)。
### 4.2 基准数据line 001更细一档 cellXY=0.05
命令:`gpr_poc build "D:\Downloads\明星路" --line 001 --cellXY 0.05 --cellZ 0.05 --out <store> --levels 1`
| 指标 | 值 |
|------|-----|
| 体维度nx×ny×nz | **44476 × 29 × 162** |
| 体素数 | 208,948,248≈2.09 亿) |
| 整卷字节int16进显存判据 | 417,896,496 B**398.54 MB** |
| data.bin含金字塔 | 199.43 MB压缩比 2.00× |
| build 峰值内存 | 4,830 MB装配阶段 double survey 主导,同 §2.4 |
| 整卷加载耗时renderB load | ≈2.84.0 s |
| renderB 进程峰值内存 | **≈509 MB**(加载整卷 398 MB + 渲染管线) |
无 build OOMcellXY=0.05 一次通过,未调粗。
### 4.3 renderB 实测指标 —— **关键发现:整卷体绘制不可行**
命令:`gpr_poc renderB <store> --frames 120`
| 指标 | 值 |
|------|-----|
| 离屏闸门复检 | OK |
| **体绘制 fps** | **INVALID整卷超 3D 纹理上限)** |
| ├ raw_fps空纹理渲染不可信 | 295.6(仅作记录,非真实帧率) |
| ├ SmartVolumeMapper 渲染模式 | 2 = GPURenderMode |
| └ vtkVolumeTexture 报错 | `Invalid texture dimensions [44476, 29, 162]` |
| **切片扫描 fps** | **54.6 fps**120 帧沿 Z 扫整卷reslice+纹理) |
| 整卷进显存 | **否**X=44476 > GL_MAX_3D_TEXTURE_SIZE=16384 |
| 降质重采样LowRes | 否(未触发;是直接纹理维度超限失败,非显存不足降质) |
| GPU 显存NVX | **N/A**(随包 VTK 安装未带 GLEW 头,无法直查 `NVX_gpu_memory_info`
但 GL 扩展列表确认该扩展存在,机器支持,仅本工具未链 GL loader |
| 进程峰值内存 | ≈509 MB |
#### 关键发现(务必看)
1. **整卷体绘制在本机离屏下不可行**:测线 001 的 X 维(沿测线方向)= **44476**
远超本机 OpenGL `GL_MAX_3D_TEXTURE_SIZE = 16384`。`vtkSmartVolumeMapper`
走 GPU 路径mode=2但底层 `vtkVolumeTexture` **无法将整卷上传为单张 3D 纹理**
`Invalid texture dimensions`。此时 `Render()` 实际未绘出体数据,
故所谓 295 fps 是**空纹理渲染的假帧率,已如实标 INVALID绝不上报为体绘制性能**。
2. **切片扫描真实流畅**:切片走 `vtkImageReslice` 输出 2D 切面 + 2D 纹理着色,
**不受 3D 纹理维度上限约束**,实测 **54.6 fps ≥ 30fps 目标**,整卷切片交互流畅。
3. **进显存判据**:整卷 398 MB 远小于 GPU 显存RTX 3060 6GB显存容量不是瓶颈
真正的瓶颈是**单轴纹理维度上限16384**,而非显存字节数。
#### 结论
- **切片**:✅ 本机离屏下整卷切片 ≥30fps54.6fps),交互流畅,满足目标。
- **整卷体绘制**:❌ 在「整卷成单张 3D 纹理」的朴素路径下**不可行**——
长测线 X 维超 GL 单轴上限。这正是 **Task 12核外 / 分块 LOD / 体纹理分区
`vtkOpenGLGPUVolumeRayCastMapper::SetPartitions`** 必须解决的问题:
要么沿 X 分区/分块上传,要么按视相机做 LOD 工作集。本任务9c按约束**不做核外**
仅如实记录此限制作为 Task 12 的硬性依据。
- 该限制与显存容量无关,是 OpenGL 纹理维度硬上限;任何「整卷一次性 3D 纹理」方案
对长测线都会撞同一面墙。