8.5 KiB
GPU PSF 累积计划
1. 目的与边界
本文件规划的是最终点源 PSF 到 HDR framebuffer 的累积加速,而不是 GPU geodesic tracing,也不是改变 catalog、lens map 或物理模型。
当前单帧数据流保持为:
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 的前提;在这些机器上仍使用流式块。
应在 optics/psf 层定义一个按块提交的 sink。概念性事件为:
typedef struct {
float x, y; /* continuous image position */
float r, g, b; /* already premultiplied by flux */
float support_radius;
} PsfEvent;
CPU worker 产生少量固定上限的事件块,填满后提交;GPU 与 CPU 以双/三缓冲方式重叠执行。 块的首版大小从 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。
验收项:
- 相同输入、固定输出尺寸、固定 PSF 参数与固定 catalog tile set。
- 记录每通道绝对/相对误差、最大像素误差、总 RGB/Y 通量差和事件统计。
- 单星(不同 phase、亮/暗、边缘和大 support)、稀疏场、密集重叠场各有测试。
- 验证
--psf-relative-tail、--psf-min-y、cache/direct fallback 的统计及图像语义一致。 - GPU 不可用、feature 不足、初始化失败或运行错误时,明确报告并回退 CPU;不得默默输出 部分帧。
- 以端到端 wall time 为准,同时记录 CPU 线程数、GPU、driver/runtime、块大小、分辨率、 catalog snapshot、Git hash 和参数。
浮点原子加法的规约顺序随调度变化,GPU 与 CPU double HDR 不会 bitwise 相同。这是可量化的 数值差异;容差要由上述固定输入对照决定,而不是预先假设。
7. 实施顺序
- 只做接口:将现有 CPU immediate splat 包装为默认 sink,输出不得变化。
- 实现 CPU 事件块 producer,但仍由 CPU sink 消费;验证事件流没有改变 HDR 和统计。
- 在工作站实施 HIP direct-atomic 原型,完成正确性和端到端基准。
- 在 ATRI 上比较流式块与整帧收集、空间重排/分桶两种输入组织;记录 host RAM 峰值、上传、 GPU kernel 和端到端时间。
- 根据 profile 决定是否实现 tile-local reduction;不因纸面 TFLOPS 推断需要它。
- 实现 Vulkan 设备枚举、feature probe 和 direct-atomic 后端;feature 不足时 CPU fallback。
- 在 ITX、Optiplex、工作站分别跑同一小基准和足够长的稳定性试验,记录真实可用矩阵。
- 只有当基准显示明显收益时,才为 WX 4100 或 Intel 核显投入 tile-reduction / 专门调优。
每一步独立提交,并保持 CPU reference、GPU runtime 层和 shader 资源的提交边界清晰。