180 lines
8.7 KiB
Markdown
180 lines
8.7 KiB
Markdown
# POC-B 实测结果(gpr_poc headless 度量)
|
||
|
||
工具:`tools/gpr_poc`(CLI),构建产物 `build/release/tools/gpr_poc/gpr_poc.exe`。
|
||
执行机:Windows 11,MSVC(VS18 Community)+ Ninja,Release(/O2)。
|
||
日期:2026-06-23。
|
||
|
||
整条地基链路:
|
||
`assembleGprSurvey → buildGprVolume → ChunkedVolumeStore::write → buildPyramid → WholeVolumeSource(load)`。
|
||
|
||
---
|
||
|
||
## 1. selftest(合成极小数据)—— PASS
|
||
|
||
命令:`gpr_poc selftest`
|
||
|
||
- 构造 2 通道合成 survey(samples=8,traces=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(实测)**
|
||
|
||
> 更新(任务 9b,2026-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-one:lastTrace+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** |
|
||
| GridSpec(nx×ny×nz) | **11120 × 8 × 162** |
|
||
| 体素数 | 14,411,520 |
|
||
| 原始体积(int16) | 28,823,040 B(27.49 MB) |
|
||
| 落盘 data.bin(含金字塔各级) | 15,317,628 B(14.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 B(27.49 MB) |
|
||
| 峰值内存 | 38 MB |
|
||
|
||
无 OOM、无超时,未调粗 cellXY 即一次通过。
|
||
|
||
### 峰值内存说明(4.98 GB)
|
||
|
||
峰值由**装配阶段**主导:同时持有 14 通道 BScan(14×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=821,TIMEWINDOW=160.352 ns,SOIL 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 渲染基准(任务 9c,2026-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 Corporation,renderer=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.8–4.0 s |
|
||
| renderB 进程峰值内存 | **≈509 MB**(加载整卷 398 MB + 渲染管线) |
|
||
|
||
无 build OOM,cellXY=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)**,而非显存字节数。
|
||
|
||
#### 结论
|
||
|
||
- **切片**:✅ 本机离屏下整卷切片 ≥30fps(54.6fps),交互流畅,满足目标。
|
||
- **整卷体绘制**:❌ 在「整卷成单张 3D 纹理」的朴素路径下**不可行**——
|
||
长测线 X 维超 GL 单轴上限。这正是 **Task 12(核外 / 分块 LOD / 体纹理分区
|
||
`vtkOpenGLGPUVolumeRayCastMapper::SetPartitions`)** 必须解决的问题:
|
||
要么沿 X 分区/分块上传,要么按视相机做 LOD 工作集。本任务(9c)按约束**不做核外**,
|
||
仅如实记录此限制作为 Task 12 的硬性依据。
|
||
- 该限制与显存容量无关,是 OpenGL 纹理维度硬上限;任何「整卷一次性 3D 纹理」方案
|
||
对长测线都会撞同一面墙。
|