190 lines
11 KiB
Markdown
190 lines
11 KiB
Markdown
# GPU PSF 累积计划
|
||
|
||
## 1. 目的与边界
|
||
|
||
本文件规划的是**最终点源 PSF 到 HDR framebuffer 的累积**加速,而不是 GPU
|
||
geodesic tracing,也不是改变 catalog、lens map 或物理模型。
|
||
|
||
当前单帧数据流保持为:
|
||
|
||
```text
|
||
image-plane mesh -> backward ray tracing -> final lens map
|
||
-> catalog query / inverse mapping -> (x, y, linear RGB, PSF parameters)
|
||
-> PSF splat -> HDR framebuffer
|
||
```
|
||
|
||
GPU 后端只替换最后的 `PSF splat -> HDR framebuffer`。CPU 仍负责 catalog 读取、
|
||
source-triangle 查询、inverse mapping、magnification、frequency shift、黑体颜色和
|
||
`--psf-min-y` 判定。它们已经在 PSF 累积之前完成;被 `--psf-min-y` 丢弃的事件不得
|
||
上传到 GPU。
|
||
|
||
这使得光追和 PSF 是按阶段顺序执行的任务。数值时空的 time slabs 在完成 lens map 后
|
||
已经可以释放,不能把它们同 GPU PSF framebuffer、cache 或事件块当成同时占用的显存。
|
||
|
||
CPU 实现始终是正确性基线和所有机器的 fallback。GPU 是可选的 `optics/psf` 后端,不得
|
||
改变亚像素位置、Moffat 参数、`--psf-relative-tail`、`--psf-min-y`、亮星 cache/direct
|
||
fallback 语义或 HDR 输出定义。
|
||
|
||
## 2. 目标机器
|
||
|
||
| 机器 | CPU / GPU | 计划角色 |
|
||
| --- | --- | --- |
|
||
| 工作站 | i7-12700K 的 8P/16T 配置;RX 9070 系列、16 GB | GPU 原型与高吞吐生产渲染机 |
|
||
| ITX | i5-10500 ES、6C/12T;Intel 核显 | CPU-only 基线;核显只在实际基准证明有益后启用 |
|
||
| Optiplex | i7-7700、4C/8T;Radeon Pro WX 4100、4 GB | 低端离散 GPU 兼容性和加速收益测试机 |
|
||
|
||
## 3. 后端接口与事件流
|
||
|
||
默认路径不构建“全帧所有星像”的事件数组,而是流式提交有限大小的事件块。数亿事件即使
|
||
每项仅 24--32 B,也会使 host-device 流量达到十余 GiB;在内存较小的机器上,整帧数组也会
|
||
造成不必要的主存峰值。
|
||
|
||
ATRI 工作站有 128 GB RAM,因此可以提供一个明确的、可选的整帧收集模式。以约 4.92 亿
|
||
事件为例,24 B/event 约为 11.0 GiB,32 B/event 约为 14.7 GiB;即使加上索引、分桶工作区、
|
||
CPU HDR 与 catalog,仍有可用空间。其可能收益不是减少需要传给 GPU 的总事件数,而是:
|
||
|
||
- 先按屏幕 tile 或 Morton order 重排事件,使 GPU 输入有更好的空间局部性;
|
||
- 一次得到准确的各 tile 负载,用于安排多个 kernel launch / workgroup;
|
||
- 为 tile-local reduction 预先构造连续的 event ranges,避免 GPU 端动态分桶;
|
||
- 将 PCIe 传输与多个 GPU 批次的执行安排得更稳定。
|
||
|
||
这是一条 ATRI 专用的空间换时间路线,必须以端到端实测证明收益后才保留。它不应成为 ITX、
|
||
Optiplex 或通用 CPU fallback 的前提;在这些机器上仍使用流式块。
|
||
|
||
当前 CPU 已在 `optics` 层建立 cache-eligible 的事件边界:
|
||
|
||
```c
|
||
typedef struct {
|
||
double x, y;
|
||
LinearRgb color;
|
||
double flux, support_radius;
|
||
} PsfCachedEvent;
|
||
```
|
||
|
||
`psf_prepare_cached_event()` 保留既有的 cache/direct/min-Y 判定,状态 0 或 2 产出该
|
||
事件;direct fallback 在 CPU 立即处理,min-Y 在上传前丢弃。`PsfEventSink` 由每个 OpenMP
|
||
worker 初始化一次、贯穿其线程生命周期,固定容量为 16,384 个事件;填满或线程结束时由现有
|
||
CPU cache evaluator 消费。此实现是 GPU producer 的正确性基线,并已通过固定 HDR reference
|
||
和完整 2MASS 前后性能记录验证。
|
||
|
||
GPU sink 将消费同一 `PsfCachedEvent` 与现有不可变 `PsfKernelCache::weights`,不得重新以
|
||
float 解析采样替代 cache 语义。首版使用有限大小的上传块并复用 device buffer;块大小从
|
||
1--16 MiB 试起,由实测决定。GPU 后端仍必须统计:cache splat、wing clip、direct fallback
|
||
和 min-Y discarded;这些计数在块完成后汇总,而不是在热循环中同步。
|
||
|
||
为降低局部热点,CPU 侧应把来自不同 image-plane triangle / worker 的事件块交错提交。
|
||
三角形内部的星像中心必定落在各自不重叠的像平面三角形内;不同三角形的 PSF wings 仍可
|
||
重叠,故这只是改善 GPU work distribution 的低成本手段,不是互斥性假设。
|
||
|
||
## 4. GPU 累积的两级方案
|
||
|
||
### A. direct global atomic 原型
|
||
|
||
一个 GPU thread 或 thread group 处理一个 PSF event,遍历其圆形支持域,并对 HDR pixel
|
||
做浮点 atomic add。这是最小的实现,适合先测:PCIe 上传、cache 读取、PSF 算术和热点
|
||
atomic contention 各自占比。
|
||
|
||
`atomic add` 的含义是“读、加、写”不可被另一线程插入;它保证多个 thread 同时向同一
|
||
pixel 加光通量时不丢更新。它不减少物理贡献次数,也不保证浮点加法顺序,因此 GPU 输出
|
||
应以容差同 CPU reference 比较,而非要求 bitwise 相等。
|
||
|
||
### B. tile-local reduction
|
||
|
||
若 direct atomic 在银河中心等密集区域成为瓶颈,则按屏幕 tile(例如 16x16 或 32x32
|
||
pixels)分桶事件。一个 GPU block 是一组共同被调度的 threads;block 内可使用 shared
|
||
memory,即该 block 专用、片上、速度快的小型临时数组。threads 先把本 tile 的许多 PSF
|
||
贡献累积在 shared memory,最后每个 HDR pixel 只写回全局 framebuffer 一次或少数几次。
|
||
|
||
这没有少算任何光,而是把大量对同一全局 HDR pixel 的竞争写入,转换为 block 内的局部
|
||
累积。代价是分桶、边界 PSF、跨 tile wings 和负载不均衡的实现复杂度。只有 direct 原型
|
||
证明 atomic 是主要瓶颈时才进入这一步。
|
||
|
||
## 5. API 选择
|
||
|
||
### HIP / ROCm
|
||
|
||
- 适合工作站 RX 9070 的最快原型;宿主端和 kernel 都接近 C/C++ 工作流。
|
||
- 用它验证算法与性能,尤其是 direct atomic 和 tile reduction。
|
||
- Gentoo 能否稳定运行由本机实际 driver/runtime、功能探测、正确性测试和长跑决定;不得用
|
||
厂商“受支持发行版”名单作为可用与否的判断标准。
|
||
- WX 4100 / Polaris 不应被假定能运行当前 ROCm 栈。因此 HIP 是高性能候选,不是三机共同
|
||
的部署承诺。
|
||
|
||
### Vulkan compute
|
||
|
||
- 是跨 Intel 核显、WX 4100 和 RX 9070 最有价值的正式可选后端;使用现有图形驱动的 Vulkan
|
||
compute path,宿主端保持 C。
|
||
- shader 编译为 SPIR-V;启动时枚举设备、显存、workgroup 限制和所需 feature。
|
||
- 浮点 `atomicAdd` 不是 Vulkan core。direct-atomic 路径必须检查
|
||
`VK_EXT_shader_atomic_float` 的对应 feature;没有则不能悄悄降级为错误结果。
|
||
- 不支持 float atomic 的设备可走 tile-local reduction,或明确回退 CPU。后者是首版可接受
|
||
行为。
|
||
|
||
### OpenCL
|
||
|
||
- 可作为单机实验或能力探测选项,但不作为主线接口。
|
||
- 各 Gentoo 主机上具体 OpenCL ICD、Mesa/Rusticl 或 AMD runtime 的设备暴露和 feature 组合
|
||
需实际检查,不能从 API 名称推断。
|
||
- 若未来 Vulkan 覆盖不足,再基于真实测得的设备矩阵决定是否值得维护 OpenCL 后端。
|
||
|
||
## 6. 精度与验收
|
||
|
||
GPU 后端必须先在小、固定 catalog snapshot 上同 CPU 的 `--psf-direct` 或 cache reference
|
||
对比。比较 linear HDR RGB/Y,而不是仅比较 tone-mapped PNG。
|
||
|
||
验收项:
|
||
|
||
1. 相同输入、固定输出尺寸、固定 PSF 参数与固定 catalog tile set。
|
||
2. 记录每通道绝对/相对误差、最大像素误差、总 RGB/Y 通量差和事件统计。
|
||
3. 单星(不同 phase、亮/暗、边缘和大 support)、稀疏场、密集重叠场各有测试。
|
||
4. 验证 `--psf-relative-tail`、`--psf-min-y`、cache/direct fallback 的统计及图像语义一致。
|
||
5. 当用户显式选择 GPU 后端时,GPU 不可用、feature 不足、初始化失败或运行错误必须明确报错
|
||
并终止该次渲染;不得回退 CPU 或默默输出部分帧。未选择 GPU 时,CPU 路径仍是独立基线。
|
||
6. 以端到端 wall time 为准,同时记录 CPU 线程数、GPU、driver/runtime、块大小、分辨率、
|
||
catalog snapshot、Git hash 和参数。
|
||
|
||
浮点原子加法的规约顺序随调度变化,GPU 与 CPU double HDR 不会 bitwise 相同。这是可量化的
|
||
数值差异;容差要由上述固定输入对照决定,而不是预先假设。
|
||
|
||
## 7. 实施顺序
|
||
|
||
### 当前状态(2026-09-05)
|
||
|
||
已完成 CPU event 路径:`PsfCachedEvent`、`psf_prepare_cached_event()` 与 per-worker
|
||
`PsfEventSink` 已进入 `frame_splat_catalog()`。固定 HDR reference 与 unit tests 验证该路径
|
||
不改变输出;在 2MASS 全天 1080p 的前后比较中,完整 event 实现相对无 event 路径版本增加
|
||
0.99% user CPU work。该记录含完整命令和原始输出,见
|
||
`benchmarks/2mass_all_sky_psf_event_sink_2026-09-05.md`。
|
||
|
||
曾有一个 float、解析中心采样的 HIP atomic spike,用于确认 HIP runtime、上传与 float atomic
|
||
可执行;它没有 cache 权重、双精度 HDR 或 production integration。其 `test-hip` target 和测试
|
||
已移除,不能作为 renderer GPU backend 的验证或运行入口。
|
||
|
||
HIP direct-atomic 的当前实现状态:
|
||
|
||
1. 已定义 production HIP sink 的 C ABI,上传 double event 与 immutable cache 权重,并复用
|
||
device/HDR buffer。正式构建选项为 `PSF_BACKEND=cpu|hip`;HIP 选择会把该层链接到 renderer,
|
||
而 CPU 选择不要求 HIP 工具链或 runtime。
|
||
在 RX 9070(gfx1201)上,`make -B PSF_BACKEND=hip SPACETIME=minkowski hip-psf-test`
|
||
的三事件重叠 cache 对照给出 `max_abs=3.4694469519536142e-18`、
|
||
`max_rel=2.7555746842446215e-16`。
|
||
2. 已接入 `frame` 的流式 sink。`PSF_BACKEND=hip` 使用单一 GPU double HDR framebuffer;
|
||
cache 事件按 16,384 项块提交,仍使用既有 bilinear phase cache、圆形支持和 wing clip 规则。
|
||
direct fallback 会完成前序 GPU 工作、在 CPU 计算、再上传 HDR 后继续,因而保持提交顺序。
|
||
3. RX 9070 上的 640×360 固定 Minkowski catalog HDR 对照逐样本一致;含 2 个 cache 事件与
|
||
1 个 direct fallback 的 `tests/data/hip_psf_mixed_catalog.csv` 场同样逐样本一致。GPU failure
|
||
会打印阶段与 HIP 错误并令该帧返回失败,不会切换到 CPU backend。
|
||
4. 已在 RX 9070 上记录一个受控的高密度 endpoint:54,160 星的 1920×1920、0.6 deg
|
||
2MASS tile 产生 26,172 个 cache event、零 direct fallback。HIP 的 2 个 batch 中 H2D
|
||
为 0.073 ms、kernel 为 2.950 s、D2H 为 11.256 ms;CPU/HIP PNG 字节一致。完整命令、
|
||
原始输出、Git 基线、线程、设备、分辨率和 PSF 参数见
|
||
`benchmarks/hip_psf_direct_atomic_dense_tile_2026-09-05.md`。
|
||
5. 该 endpoint 说明当前时间主要位于 device kernel,而非 PCIe;它**不能单独证明** kernel
|
||
时间主要来自热点 atomic contention(仍混有每 event 的 PSF 遍历与 cache 读取)。因此暂不
|
||
实现 tile-local reduction。下一步应在资源隔离条件下,以不同屏幕密度和 PSF 支持域分离竞争
|
||
效应;只有该证据显示竞争为主导且 tile-local 的整帧端到端测量获益时,才保留分桶/重排实现。
|
||
ATRI 的整帧收集/重排同样必须以端到端收益证明。
|
||
6. HIP 路径稳定后再评估 Vulkan 的可移植后端及其他机器的实际设备矩阵。
|
||
|
||
每一步独立提交,并保持 CPU reference、GPU runtime 层和 shader 资源的提交边界清晰。
|