Document the producer-private adaptive path, the dummy support workload diagnostics, the negative result of the old serial binning and the 2026-09-13 full-day comparison (splat 282.944 s vs atomic 481.417 s). Add the corresponding raw logs, hotspot fixtures and runner evidence, and lay out the staged plan toward a sub-240 s full-day render without changing the default atomic path.
35 KiB
HIP PSF 有界真实事件回放与像素归约实验(2026-09-07)
结论与交付
当前方向(2026-09-13):搁置旧串行 adaptive 的慢因追溯,在新版 worker 私有预分桶 adaptive 上优化生产管线。以下各日期记录保留历史结论;当前结果和下一步目标以 “2026-09-13 全天复测与下一步目标”一节为准。
已实施原计划的有界捕获/回放、16×16 和 32×32 按像素归约原型、独立 CPU producer
诊断及正确性回归。原型保留在测试程序中,未替换生产 HIP 路径。
实现于 2026-09-11 提交为 7f5ec1a;以下日志和 hash 保留 2026-09-07 测量时的状态。
RX 9070 上,65,536 个真实银心视场事件的累积回放中位数从 104.107 ms 降至 69.823 ms(16×16,约 1.49×)。含公共 GPU 初始化为 137.111 → 102.323 ms(约 1.34×)。 但同等贡献的分散对照中,16×16 从 85.302 ms 退化至 104.389 ms;32×32 为 79.899 ms。 强放大样本的 32×32 结果波动区间与 atomic 重叠,不能确认稳定收益。因此尚不足以选择 一个通用生产默认算法;后续集成应先考虑分布选择及生产流式 producer 的端到端对照。 没有运行完整全天渲染,也没有推断新的全天加速比。
2026-09-11 自适应选择后续实验
在提交 11e703e33dffb1ff168ba11dd922e68b448116b9 之上增加了仅用于回放的
adaptive 模式,production sink 仍未改变。选择器逐个 16,384-event chunk 扫描
32×32 中心 tile 占用;chunk 至少有 8,192 events、且平均每个占用中心 tile 至少
32 events 时选择 tile16,否则选择现有 atomic。该阈值是基于本页固定输入提出的实验
假设,不是跨场景或跨设备参数。
选择扫描不构建 support 引用,四个样本的中位成本为 0.037--0.455 ms。tile 路径使用 独立的有界 event device buffer,不复用 production 双 staging slot,因此同一 stream 内 可以按 chunk 混合 atomic/tile;mixed fixture 实际覆盖 2 个 tile chunk、1 个 atomic chunk 和中途 direct fallback。所有额外 scratch 仍在 replay sink 创建时一次分配,未进入 renderer。
同一新 binary(SHA256
121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151)串行运行,
每项三次;表中为包含选择、分桶、上传、kernel、合并、下载和清理的 replay_wall
中位数:
| 65,536-event 输入 | paired atomic | paired tile16 | adaptive | adaptive 选择 |
|---|---|---|---|---|
| 银心密集 | 95.018 ms | 67.354 ms | 67.834 ms | 0.177 ms |
| 同贡献分散 | 78.203 ms | 99.693 ms | 80.092 ms | 0.455 ms |
自适应路径在密集输入相对 paired atomic 快约 1.40×,距固定 tile16 中位数 0.7%;在分散 输入保留 atomic,距其 paired 中位数 2.4%。另外两个真实输入的自适应中位数为强放大 21.617 ms、普通区域 18.347 ms,分别选择 1/1 tile chunk。银心选择 4/4 tile chunks, 分散对照选择 4/4 atomic chunks。此结果支持继续研究 production 流式集成,但尚未包含 OpenMP producer 与 sink 锁竞争,也没有授权用本回放结果宣称完整全天加速。
全部 adaptive/mixed 检查通过原有 finite、double HDR 和 RGB/Y 通量阈值;最坏
max_abs=5.96856e-11、max_rel=5.95958e-13、RGB 通量相对差
<=2.83233e-14、Y <=1.15036e-14。make -j1 test 与 production HIP primitive
也通过。第一次在受限沙箱内运行明确失败为 no ROCm-capable device is detected,随后只在
获准的主机 GPU 环境执行;失败记录保留,没有删除或覆盖。
原始证据:
- 构建:adaptive_build_host.log;
- adaptive 三次:
adaptive_{center_65536,dispersed_65536,lensed_16384,ordinary_12765}_host_{0,1,2}.log; - paired 基线:
paired_{center,dispersed}_{atomic,16}_{0,1,2}.log; - mixed、CPU 与 HIP 回归:
adaptive_boundary_mixed_host_0.log、adaptive_cpu_regression.log、adaptive_hip_primitive_host.log; - 受限环境失败:
adaptive_center_65536_0.log。
每份日志均保留完整命令、45/90 s timeout、Git hash、binary hash(适用时)、程序原始输出、 process wall 和 exit status。所有性能进程均由现有独占 runner 串行执行,未与其他 renderer 或 profiler 并发。
2026-09-12 持续回放与 production 集成
在提交 2d01c2c101ccea8193a64bb46ceafca3009f0ef5 之上的未提交实现中,回放器增加了
1--512 轮有界重复模式,用同一真实事件流测试持续负载。重复模式不把累计 128/256 轮的
GPU HDR 与单轮 CPU reference 比较,因而输出明确标记 validation=skipped-for-sustained-timing;
单轮真实输入与 mixed boundary 仍执行原有 double HDR、RGB/Y 通量和 finite 检查。
原 replay tile16 在密集输入的 256 轮完整 wall 为 12.968 s,atomic 为 14.326 s,只有 1.10×--1.18× 的持续收益;tile accumulation 本身仍约快 1.4×,CPU 的整屏嵌套列表分桶 约占 1.8--1.9 s。不同运行顺序下的 128 轮 adaptive 为 6.372--6.880 s,对应 atomic 7.149--7.165 s,证明短回放的 1.40× 完整收益不能直接外推。
production sink 随后接入稀疏 touched-tile 分桶和可复用有界 scratch。默认保持 atomic;
HIP_PSF_ACCUMULATION=adaptive 启用与 replay 相同的中心密度选择规则。32 MiB references、
2 MiB tasks 或 128 MiB partials 超限时按 chunk 回退 atomic,不改变 double RGB、四点 phase
cache、圆形 support、wing clipping 或 direct fallback 顺序。
最终同 binary(SHA-256
c560c193e1dc2104030ed804ea68e16ab7576592191dbf147b917a6e097a66b6)连续回放
65,536 个真实银心事件 128 轮:
| production sink | 完整 replay wall | GPU 阶段 | selector | CPU bin | upload | batches |
|---|---|---|---|---|---|---|
| atomic | 7.164 s | 7.132 s | 0 | 0 | 0.023 s | 512 atomic |
| adaptive | 4.631 s | 3.875 s | 0.018 s | 0.607 s | 0.091 s | 512 tile16 |
完整 replay 为 1.55×,记录的 GPU 阶段为 1.84×。同 binary 的 64 轮同贡献分散
输入中,adaptive 选择 256/256 atomic chunks,完整 wall 为 3.167 s,直接 atomic 为
3.169 s,差异在 0.1% 内。最终 dense 单轮检查的
max_abs=2.71051e-19、max_rel=1.96115e-14。最终 mixed boundary
覆盖 2 个 tile16、1 个 atomic chunk 和中途 direct fallback,最坏 max_abs=5.96856e-11、
max_rel=5.95958e-13,RGB/Y 通量阈值均通过。production primitive 在 adaptive 环境下也
通过,max_abs=2.84217e-14、max_rel=7.53192e-16。
三 tile、21,087-star renderer 配对使用同一 4K lens map 和同一 production binary
(SHA-256 f51cbccac135502440f005c5d61d95d6004be7d4ec5cd09bfe04bab53053143d)。
atomic/adaptive 均产生 156,837 events;adaptive 选择 14 tile16 + 2 atomic batches,kernel
为 0.118894 s,对照 0.169212 s,splat wall 为 0.236/0.285 s。两张 PNG 的 SHA-256 都是
99a971fac7f5e66f0a1aafd0921b61f16fcb933c9488320f95e423542d3b6a6d。约 1.4 s 的完整
进程受 cache build 等固定成本波动支配,不能用 process wall 判断这项优化。
随后使用同一 4K lens map、598,264,924 events 和 36,530 batches 运行了完整全天 adaptive 渲染。它推翻了上述有界样本的外推:
| 完整全天 | splat wall | kernel | CPU bin | selector | upload | process wall |
|---|---|---|---|---|---|---|
| atomic | 480.500 s | 477.302449 s | 0 | 0 | 1.411367 s | 533.62 s |
| adaptive | 586.763 s | 416.265471 s | 155.302 s | 2.212 s | 7.506981 s | 640.35 s |
adaptive 的 GPU kernel 只减少 61.037 s(12.79%),而串行关键路径上的 CPU 分桶增加 155.302 s,splat wall 因而增加 106.263 s(22.12%),完整进程增加 106.73 s(20.00%)。 36,515/36,530 batches 被选为 tile16,说明中心 32px tile 密度无法预测完整 47px PSF support 扩张后的 references、tasks、列表长度和分桶成本。atomic 从有界回放的 13.93 ms/batch 到全天的 13.07 ms/batch 没有恶化;tile kernel 则从有界样本的 7.57 ms/batch 变为全天的 11.40 ms/batch,CPU 分桶另需 4.25 ms/batch。串行分桶是已确认的额外成本;GPU 阶段变慢的具体原因未定位, 不能仅凭这些时间排除时钟或其他系统因素。
正确性仍成立:atomic/adaptive PNG 的 SHA-256 都是
c63df730c7f927fc6b6ae17df5ffbad1d2bb44631a5821557150d00d6269a3e4。两个 HDR FITS
共有 24,883,200 个 float,113 个因累积顺序不同;max_abs=2.38418579e-07、
max_rel=1.18905923e-07。这项旧串行分桶 adaptive 实现是历史负结果,不能外推为新版并行预分桶的结论;
默认继续保持 atomic。当时提出的下一轮实验是直接度量 support-expanded 引用工作量,并在
重新跑完整全天前用真实流式 producer 验证并行预分桶或 GPU 分桶能否把成本移出串行关键路径。
完整 adaptive 原始输出保存在 full_production_adaptive_user.log(SHA-256
ec7b41d56a76cb93383737c30c6c6055bdb53b9b0cff54034333d96a841b1f36);该用户命令未嵌入
Git/binary hash,运行后工作区 binary 的 SHA-256 为
f51cbccac135502440f005c5d61d95d6004be7d4ec5cd09bfe04bab53053143d,不可仅凭事后 hash
证明执行期间 binary。atomic 数字来自同一任务先前保留的终端输出。
2026-09-12 producer 私有并行预分桶原型
在上述完整全天负结果之后,将 adaptive 选择与 support-expanded CPU 分桶移到每个 OpenMP
producer 私有的 HipPsfPreparedChunk,在获取 sink 共享锁前完成;单个 sink 仍独占 GPU
HDR、stream、device scratch 和稳定的上传 staging。direct fallback 先准备本 worker 的待提交
chunk,再在同一锁内完成提交、HDR 下载、CPU splat、HDR 上传。原 hip_psf_sink_submit 仍用于
单线程回放兼容,正常生产默认 atomic 未变。新日志记录 tile references、tasks、merges 和
单 chunk 峰值,以便下一次评估完整 support 工作量。
同一 65,536-event 银心固定输入重复 128 轮,均为 512 个 tile16 batches。新 binary 的配对
回放结果如下(两者均通过 128 × CPU double reference,max_rel=2.14616e-14):
| 生产 sink 回放 | replay wall | 累计 CPU bin | GPU 阶段 | process wall |
|---|---|---|---|---|
| sink 内串行分桶 | 3.886 s | 0.549 s | 3.659 s | 5.778 s |
| 16 worker 私有预分桶 | 3.958 s | 0.709 s(各 worker 求和) | 3.670 s | 5.873 s |
此输入上并行预分桶没有端到端收益,且累计 CPU 工作与 RSS 上升(约 716→770 MiB)。由于这 份输入已被全天结果证明低估真实分桶与 tile kernel 成本,此试验仍不能判断全天会否受益, 更不能宣称 61 s 的 kernel 收益已被回收。**不据此再跑完整全天。**需要先取得代表实际 36,530 chunks 的 support-expanded references/tasks 分布和并行分桶 wall,再决定是否继续此方向。
真实小型 4K lens-map renderer 中,16 workers 处理 156,837 events,13 tile +3 atomic
batches;13 个 tile chunk 共 6,145,194 references、64,056 tasks、5,465 merges,单 chunk
最多 561,449 references。PNG SHA-256 与先前 atomic 输出同为
99a971fac7f5e66f0a1aafd0921b61f16fcb933c9488320f95e423542d3b6a6d。另一个
32,771-event mixed boundary 回放包含 2 tile +1 atomic chunk 和 direct fallback,通过 CPU
double reference,max_abs=5.96856e-11、max_rel=5.95958e-13。HIP primitive 与
make -j4 ENABLE_PNG=1 test 均通过。
新原始日志:parallel_prebin_{serial_128_validated,16workers_128_validated}.log、
parallel_prebin_renderer_workload.log、parallel_prebin_mixed_boundary.log、
parallel_prebin_hip_primitive.log。先前 parallel_prebin_16workers_128.log 因 OpenMP
reduction(max:failed) 的私有初值而没有提交事件;原始失败保留,修正为 reduction(+:failed)
后的 *_v2.log 才是首次有效回放,最终数字以上述带 scaled reference 校验的日志为准。
为获取不经 GPU 的真实全天 support 分布,dummy 后端增加显式
DUMMY_PSF_SUPPORT_STATS=1 诊断:每 worker 保存最多 16,384 个事件,在 chunk flush 时按
production 的 cache-limited 矩形 support 统计 16px references、touched tiles、按 256
references 切分的 tasks、最大单 tile 列表和第一遍计数耗时。它不生成 HDR、不 materialize
references、不上传 GPU,不能把第一遍耗时等同于完整两遍分桶成本。21,087-star 小样通过,
原始记录为 parallel_prebin_dummy_support_small.log;该样的 chunk 边界受 OpenMP 动态调度
影响,不与 HIP renderer 的逐 chunk 列表配对。完整全天诊断结果见下文。
下一次完整全天诊断使用与已跑的 dummy 任务相同的参数,只额外设置环境变量;输出路径仅 满足 CLI,dummy 不写图像:
OMP_NUM_THREADS=16 OMP_DYNAMIC=FALSE DUMMY_PSF_SUPPORT_STATS=1 \
./build/Release/schwarzschild_sky_dummy --verbose \
--psf-relative-tail 1e-8 --psf-min-y 0 --max-cache-psf-flux 1e8 \
--all-sky-catalog assets/2mass/processed/all_sky --exposure 1e13 \
--psf-fwhm-pixels 2.7 --psf-moffat-beta 4.5 --catalog-load-workers 4 \
--lens-map-input output/lens/schwarzschild_galactic_center_R100_45deg_16_4_4k_.grlens \
--output /tmp/2mass_dummy_support_diagnostic.png
用户随后运行了上述完整全天 dummy 诊断;原始终端输出为
full_dummy_support_user.log,
SHA-256 992a3109de28a338c53af229b6a3b4083659a835f78929c36d36178358a6d5e0。
日志未嵌入执行时 Git/binary hash;运行后本地 dummy binary 的 SHA-256 为
2550fbdc7367ec4d56bdf87894e1322d7f4af5165e93a17af3e6a37806c0649a。
同一 343,363,141 stars 产生 598,264,924 cached events,0 direct/wing/discard;
64,440 catalog tiles 全部加载,49.020 s;16 worker 分类/chunk wall 81.760 s。zsh time
给出总时间 2:11.91;zsh 对 pipeline 中的 tee 另列一行,不能把两个 2:11.91 相加。
该次动态调度产生 36,508 个满 chunk、16 个 partial;与 HIP 的 36,530 batches 不作逐批
配对,但总事件数一致。
| 全天满 chunk support 统计 | p50 | p90 | p99 | max |
|---|---|---|---|---|
| 16px references | 746,748.5 | 802,816 | 802,816 | 802,816 |
| touched 16px tiles | 49 | 168 | 1,036 | 1,521 |
| tile tasks | 2,975 | 3,136 | 3,435.93 | 3,733 |
| 最大 tile 列表 | 16,384 | 16,384 | 16,384 | 16,384 |
| 第一遍计数 | 0.807 ms | 0.919 ms | 1.049 ms | 7.969 ms |
全部 chunk 合计 27,216,790,943 references、107,847,441 tasks,worker 第一遍计数时间之和
29.347 s。这是并行 worker 时间之和,不是额外 wall time,也不包括第二遍写 references、
任务构造、锁内 staging 或 GPU 上传。全天 HIP 串行完整分桶为 155.302 s,不能拿 29.347 s
直接替换它。第一遍显示每个事件平均覆盖约 45.5 个 16px tile;满 chunk 的 p90 已到
16,384 × 49,且最大列表从中位数起就是整批事件。
对旧真实 center_65536.events 逐 chunk 用相同 support 矩形计算,四批 references 为
745,430 / 725,200 / 753,474 / 749,671,接近全天 p50;但 touched tiles 为
96 / 162 / 203 / 222,最大列表仅 14,637 / 9,099 / 11,188 / 9,220。因此先前有界
样本只匹配了引用总量,没匹配热点集中度。为区分这两个量,make_hotspot_fixture.py 把
原事件平移到相同整数像素,或保留约 8×8px 位置散布;颜色、flux、support 原样保留,
亚像素余数仅受 double 舍入影响。这两份明确是反事实 GPU workload,不是物理星像。
固定热点每批恰好 802,816 references、49 tiles、3,136 tasks、最大列表 16,384;
输入 SHA-256 分别为 de39e07d420f70aaa2f7309d209e58a1091d2bea4ca6d8332366e6944f19347b
与 87f90c2e43845962702e1643f9b7a635108b75b6e21a30080650442745cadcf6。
| 128 轮、512 批回放 | atomic wall | tile 串行 wall | tile 并行 wall | atomic GPU 阶段 | tile GPU 阶段 |
|---|---|---|---|---|---|
| 同一整数像素 | 7.711 s | 4.001 s | 4.071 s | 7.677 s | 3.760 s |
| 8×8px 散布 | 6.482 s | 3.949 s | 4.046 s | 6.447 s | 3.714 s |
全部回放通过按轮数缩放的 CPU double reference,tile 的最大相对误差不超过
3.30e-14。此对照说明 refs/tile/list 聚合量不足以重现全天 tile GPU 阶段
416.265/36,530 = 11.40 ms/batch:即使强制匹配 p90 热点,回放仍约
7.3 ms/batch。另外在 center_65536.events 的同一回放进程内放入 15 个 CPU 忙等线程,
atomic/tile GPU 阶段为 7.126/3.669 s(512 批),几乎仍是无忙等线程的
7.13/3.66 s;简单主机抢占也未重现全天差距。上述 workload 与争用实验均为诊断性
反事实,不能改变真实全天 adaptive 慢 20% 的结论。
原始配对日志:hotspot_{atomic,adaptive_serial,adaptive_parallel}_128.log、
hotspot_jitter8_{atomic,adaptive_serial,adaptive_parallel}_128.log、
busy_center_{atomic,adaptive}_128.log。全天 adaptive 原始进度每隔约 5 秒报告累计 HIP
阶段:首尾约 7–8 ms/batch,中间约 12–13 ms/batch 持续数万批。这提示当前固定 65,536
events 输入未覆盖真实流中的长期困难区段,但也不能排除其他随时间变化的系统因素;
原因仍未定位。当时提出从该区段捕获真实 events 和逐批 GPU/CPU 明细;
2026-09-13 已搁置这项旧版追溯,不再作为新版推进的前置条件。
其余原始证据为 final_production_{atomic,adaptive}_128.log、
final_production_adaptive_dense.log、
final_production_dispersed_{atomic,adaptive}_64.log、
final_production_adaptive_mixed.log、final_hip_test_adaptive.log 和
final_renderer_{atomic,adaptive}.log。每份日志包含完整命令、timeout、Git hash、binary hash
及原始输出。production 默认值没有改变。
实现入口:
- capture_psf.c:调用真实 producer 的测试专用 consumer,捕获或诊断,不生成 HDR。
- replay_psf.hip:CPU double reference、现有 atomic、两种 tile 原型。
- make_psf_fixture.c:单独标记的合成边界/热点/wing fixture。
- test_psf_capture.py:边界限制、分类、串行/并行/索引摘要、拒绝覆盖验证。
- 全部原始证据与索引。
2026-09-13 全天复测与下一步目标
用户在重新构建 worker 私有预分桶版本后,再次完成同配置全天 adaptive 渲染;随后
git stash 回到 2d01c2c,重新构建并复测原 atomic,之后用 git stash pop 恢复修改。
该 HEAD 的 HIP 实现不读取 HIP_PSF_ACCUMULATION,所以 atomic 复测命令虽仍写着
adaptive,实际是 atomic;不能把输出文件名或环境变量当作算法证据。
| 全天实现 | splat wall | GPU event 阶段 | CPU bin | upload | process wall |
|---|---|---|---|---|---|
| 历史 atomic | 480.500 s | 477.302449 s | 0 | 1.411367 s | 533.62 s |
| 旧串行 adaptive | 586.763 s | 416.265471 s | 155.302 s,串行 | 7.506981 s | 640.35 s |
| 新并行预分桶 adaptive | 282.944 s | 256.184375 s | 134.374 s,worker 累加 | 7.184765 s | 335.75 s |
| 本次 atomic 复测 | 481.417 s | 478.336515 s | 0 | 1.432135 s | 534.37 s |
四次总事件数均为 598,264,924、batches 均为 36,530;两次 adaptive 都选择 36,515 tile16 和 15 atomic batches。新 adaptive 无 direct/wing/discard,references 为 27,216,530,468、 tasks 为 107,238,420、merges 为 2,802,462,峰值 references/chunk 为 802,816。 新 adaptive 和旧 adaptive 均已使用相同 payload 的黑体 LUT;catalog 加载分别为 49.334/50.104 s。新版 bin 时间是各 worker 的经过时间之和,可以与 GPU 重叠,不能加到 splat wall 上,也不能与旧版串行 bin 作等口径的关键路径比较。
atomic 的 splat/GPU 复测仅比历史值高约 0.2%。相对本次 atomic,新 adaptive 的 splat 快约 1.70×、GPU event 阶段快约 1.87×、完整进程快约 1.59×。这支持继续推进新版; 尚不是相同 binary 内的 atomic/adaptive 配对,也不证明新版全天 HDR 数值正确性。 新旧 adaptive 的 splat 差 303.819 s,其中 GPU event 阶段差 160.081 s;不能把全部收益 归因于分桶并行化。旧版 GPU 阶段为何更慢仍未知,保留历史证据,停止专项追溯;仅当 新版出现可重复退化或正确性问题且旧版信息有助定位时重新调查。
新 adaptive 完整原文见 full_parallel_prebin_adaptive_user_2026-09-13.log; atomic 复测仅收到结尾摘录,原样保存为 full_atomic_redo_user_2026-09-13_excerpt.log。 两者均未提供运行时 binary hash,摘录不能代替完整命令和完整运行日志;本次只更新文档, 没有重新运行 benchmark 或比较新生成的全天 HDR。
新版优化目标与验证顺序(待实施)
目标是在相同 RX 9070、4K lens map、全天 catalog、PSF/曝光/黑体参数和 HDR/PNG 输出下, 将完整进程从 335.75 s 推进到 240 s/张以内。这是待验证目标,不是性能承诺;不能通过 降低精度、删减事件、改变 tail/min-Y、缩小输入或省略输出来达标。atomic 保留为参考和 显式可选路径,本次不修改默认算法。
用户全程观察新版的 btop:GPU 常在约 94%,会反复降至约 80%,并非偶发;整机 CPU 持续满载。用户另报告原 atomic 能吃满 GPU。旧串行 adaptive 当时没有观测,不能推断它 不存在 GPU 不满载现象。上述是人工观测,未保存同步遥测,不能据此量化净算力利用率。 新版 generation/submission 累计分别为 814.275/3712.364 s,后者包含分桶、锁等待和 提交/完成等待;atomic 复测的 GPU 阶段占 splat wall 约 99.36%,进程仍为 1461% CPU。 CPU 满载不等于有效 producer 工作,忙等是需测量的嫌疑,尚未定量确认。
新版非 splat 阶段约 52.806 s;即使消除 splat wall 与 GPU event 阶段之间的全部 26.760 s,总进程仍约 309 s。若其他阶段不变,240 s 目标要求 splat 不超过约 187.2 s, 比当前 GPU event 阶段还低约 27%。该 event 区间包围 prepare/accumulate/merge,可能含 提交间隙,不等同于三个 kernel 的净执行时间。因此同时调查管线空隙和 GPU 执行成本, 不能把 btop 达到 100% 当作验收标准。
- 先比较已有新版 adaptive 与 atomic 全天 HDR:finite、逐像素误差、RGB/Y 总通量, 使用现有正确性阈值;记录输出 hash,不为这一步重跑全天。
- 增加可关闭的有界诊断,拆分 CPU 分桶、锁等待、锁持有、GPU 完成等待、staging 和 提交时间,记录线程 CPU time;GPU 分别测 prepare、accumulate、merge,并保留原总区间。 在新版代表性真实流式小样上同步记录 GPU busy、时钟、功耗、温度,先验证测量开销。 固定事件回放用于隔离成本,不能单独替代生产 producer/sink 的端到端证据。
- 若批间空隙显著,优先评估双缓冲 staging/上传,使下一批准备与当前批 GPU 执行重叠; 若共享锁争用显著,再对照专用提交线程加有界队列。这些是待验证候选,不是已选定实现。 明确缓冲 ownership、完成后复用和有界背压;单 sink 持有 GPU HDR,保留 direct fallback 的 finish/download/CPU/upload 顺序,不引入 per-event task 或无界排队。
- 管线改善后重测剩余成本;若主要时间仍在 kernel,则优化占比最大的实际 kernel;若 catalog 加载成为主要限制,再单独评估输入阶段。保留密集、分散和 mixed/direct 回归。 有界配对采用相同 binary/输入、预热后至少三次交错顺序复测,报告 wall、CPU time、 GPU 分阶段及波动,不累加重叠 worker 时间。每次预设 timeout,串行独占执行,保留完整 命令、Git/diff/binary/input hash、原始日志与退出码;GPU 不可用直接失败。
- 有界正确性与收益验证后再另行安排全天配对确认,同时报告完整进程和分阶段时间。 未达到 240 s 时记录剩余差距及实测瓶颈;不为解释旧版而额外运行全天。
环境与测量纪律
Git 基线 5eccc31c99db96de2a0597babf2fd4c2149e91e7,测量时在此基础上有未提交修改。
没有覆盖用户已有的计划修改。生产 src/hip_psf.hip 未改;src/frame.c 的诊断钩子
仅在 standalone 测试编译时启用。每次直接执行的 binary SHA256 在相应日志中;
源码、binary、lens map hash、
宿主环境、
构建命令与 build*.log 保存完整配置。
Release / C -O2 -march=native / HIP -O2 --offload-arch=gfx1201,HIP 7.2,RX 9070。
回放 CPU reference 为串行;diagnostic 最多 16 workers;混合 renderer fixture 为 4 workers。
各进程重建相同 immutable cache:FWHM=2.7、beta=4.5、tail=1e-8,64 phase intervals、
47px cache radius。没有清除文件系统 page cache;输入是重复读取的固定小文件。
所有测试进程串行,回放超时 45 s、缩小 renderer 超时 60 s;未出现测试超时。
早期 v3_* 期间部分编译活动重叠,全部 v3_* 仅用作探索/正确性证据。
下表只用构建和回归结束后的 final_* 三次独立复测,不引用受构建干扰的时间。
run.py 记录命令、原始 stdout/stderr、退出码和进程 wall,失败立即停止,限时进程被 kill
后会 wait/reap;独占锁及启动前的进程检查防止本套工具重叠运行。
固定输入、选择规则与实际覆盖
使用已有 3840×2160 Schwarzschild lens map,不重新 tracing/refine。只读取两个指定 catalog tile 的均匀 8,192 行子集,见 输入 manifest 和 重建脚本。没有遍历完整全天 catalog。
捕获器限制 CSV≤8 MiB、stars≤32,768、lens map≤64 MiB/单帧、triangle 范围≤131,072、
缓存事件≤65,536、分类总数≤131,072。按 triangle ID、原 catalog 顺序捕获,保留所有
7 个 event double,文本用 17 位有效数字 round-trip;header 保存实际数量与 PSF 参数。
triangle 范围 [0,130882);按未截断的局部 magnification 再筛选:
| 区域 | 原始 tile | magnification | 最大捕获实际数 | 占用 32px 中心 tiles | 最大中心密度 |
|---|---|---|---|---|---|
| 普通区域 | RA252/Dec048(Dec −42°) | [0,1.2) | 12,765 | 8 | 4,691 |
| 银心视场密集区域 | RA262/Dec060(Dec −30°) | [0,2) | 65,536(到上限) | 30 | 7,778 |
| 强放大区域 | 同上 | [2,1e6) | 16,454 | 367 | 176 |
普通、强放大子集用完后没有复制事件凑足 65,536。事件文件名后缀表示请求上限,实际数量 以 header 和 manifest 为准。实际 bbox、flux/support 范围、中心 tile 分布及事件 hash 见 events_manifest.json。三种真实输入的 support 均为 45.84777786185942px;变化 support/wing/边缘另由合成 fixture 覆盖。
分散对照只平移完整处于画面内部的事件中心,保留 fractional phase(浮点平移舍入以内)、 flux 和 support;本来裁切的事件不移动。每次都重新计算并断言实际 event–pixel 贡献数 完全不变:真实和分散的 65,536 事件均为 432,818,979 个贡献。没有以裁切减少工作量。
原型与 ownership
每 chunk≤16,384 events。CPU 按 cache 遍历 support 的完整包围矩形建立所有相交 tile 引用,PSF wings 可以进入多个 tile;GPU 用原来的圆形行范围再筛选,继续四点 phase cache 插值和 double RGB。每个像素由一个线程累计,不使用全局 double atomic。
第一次朴素实现反复计算 phase、sqrt/行范围,4,096 普通事件的回放约 25–27 ms,慢于 atomic。第二版为每个 chunk 在 GPU 预计算 phase、颜色×flux 和行范围,然后供像素线程复用。 分散对照随后触发 128 MiB 部分和限制,进程已停止。最终版让≤256 引用的单列表 tile 直接写回独占 HDR 像素;只有长列表分段才写部分和,第二阶段按固定 task 次序相加。 这种修正保持内存上限,避免为整屏稀疏 tiles 分配一幅额外 double HDR。
设备上固定复用:references 32 MiB、tasks 2 MiB、starts 128 KiB、partials 128 MiB, 以及最多 16,384 事件的 Prepared/行范围约 12.875 MiB;合计额外预留 175 MiB。 超出引用/任务/部分和容量立即报错,无隐式切换。全部缓冲由单个实验 sink 持有,单 stream 顺序消费、同步后复用;每个 partial 元素都被覆盖写入,不需要 memset。最终样本实际 scratch 使用峰值约 37.26 MiB,整个 CPU-reference+GPU 进程 RSS 最大 717,172 KiB。 预留量和实际用量不同,RSS 包含 CPU HDR/reference/cache,不能当作生产额外 RAM。
独立最终回放结果
下表是 replay_wall 中位数(ms,三次):包含 scratch 分配、分桶、上传、预计算、累积、
合并、下载、清理,排除公共 sink/cache 初始化和 CPU reference。日志另报 complete_replay
(加公共 GPU sink 创建)、CPU_reference、cache build、完整 PROCESS_WALL,避免混淆。
| 输入 | 实际 events | atomic | tile16 | tile32 |
|---|---|---|---|---|
| 普通 | 12,765 | 26.423 | 18.511 | 19.286 |
| 银心视场 | 16,384 | 31.803 | 22.621 | 23.247 |
| 强放大 | 16,384 | 26.536 | 23.814 | 25.388 |
| 银心视场 | 65,536 | 104.107 | 69.823 | 73.093 |
| 同等贡献分散对照 | 65,536 | 85.302 | 104.389 | 79.899 |
含公共 GPU 创建的 65,536 密集回放为 137.111 / 102.323 / 105.949 ms。
强放大 tile32 回放范围 22.801–29.410 ms,atomic 25.932–27.395 ms;三次样本不足以
证明这里的稳定提升。完整数值、范围和全部重复见 summary.log
与 final_*.log,由 final_cases.py 串行生成。
分阶段日志同时记录实际贡献吞吐量。atomic 上传/kernel/download 使用 HIP event; 候选分桶为 CPU wall,prepare/accumulation/merge 为包含 launch+stream sync 的 host wall。 它们不能拿来做精确的纯 kernel 周期归因,完整回放 wall 才是算法比较依据。 分散 tile16 的分桶本身约数十 ms,足以抵消其累积优势。
编译器资源记录 显示 atomic kernel
62 VGPR,prepare 37,tile accumulation 21,merge 18,private segment 均为 0。
生成的 atomic 代码仍有三个 global_atomic_cmpswap_b64 循环;候选不需要它们。
这不是运行时 cache/occupancy/FP64 counter 测量,不能据此分摊 atomic contention 的比例。
没有使用降低 HDR 精度、近似黑体颜色或改变 min-Y/tail 的方法。
CPU producer 独立测量
诊断 consumer 在正常查询、inverse mapping、频移、黑体积分与 prepare/classification
之后,仅计数与计算摘要。输出明确标记 DIAGNOSTIC ONLY, no HDR。
parallel 模式每 worker 计数/摘要独占;汇总 checksum 与事件顺序无关,串行捕获仍保留顺序。
indexed 模式从同一有界 CSV 预构建原生一度 tile 索引,worker 查询前已完全只读,不执行 I/O。
为了比较完整相同工作而不受事件上限/调度停止次序影响,银心诊断 triangle 范围缩为
[0,40151),其他仍 [0,130882)。所有以下运行均未触顶,四种模式逐项核对
cached/wing/direct/discarded/events 和 checksum 完全一致。各三次中位数:
| 输入 | events | memory/1 worker | memory/16 | indexed/1 | indexed/16 |
|---|---|---|---|---|---|
| 普通 | 12,765 | 2.8123 s | 0.3502 s | 0.0729 s | 0.0125 s |
| 银心视场 | 16,895 | 1.1472 s | 0.1383 s | 0.0535 s | 0.00986 s |
| 强放大 | 16,454 | 1.3845 s | 0.1493 s | 0.6836 s | 0.0751 s |
CSV 全扫描明显夸大查询成本;生产判断应使用 indexed 列。强放大子集遍历大量分散 triangle,
其独立 producer 时间在这一小输入上高于 GPU 回放,说明进一步加速 GPU 未必改善同等比例的
端到端时间。这不是全天 CPU 下限,也不能与另一事件数量的回放直接相减。
未修改黑体积分;没有把 summed generation / workers 当作独立计时。
正确性与失败记录
- 全部真实回放、分散对照和最终 45 次独立复测通过 finite/double HDR 检验。
- 边界 fixture:32,771 events,33 wing-clipped, exact/intermediate phases、屏幕内外、热点、三 chunk/缓冲复用。atomic、tile16、tile32 均覆盖中途 finish/download → CPU direct → upload → 继续累积。
- 全部最终+边界最大
max_abs=5.96856e-11、max_rel=5.98529e-13;最坏 RGB 总通量 相对差≤2.83419e-14,Y≤1.15193e-14。沿用旧 replay 的 abs/rel<1e-10,另增加总 RGB/Y 相对误差≤1e-10 的检查,没有为结果放宽门槛;现有生产 primitive 的 rel≤1e-12 也通过。 - 捕获/索引诊断回归通过:真实 mixed classification cached=2/direct=1,min-Y 场 discarded=3;串行/并行/索引摘要一致;验证 event cap、非法范围、拒绝覆盖已有文件。未用提高 min-Y 代替 producer 测量。
- HIP primitive、 Minkowski mixed/min-Y integration通过。
- Schwarzschild CPU / HIP同一 8,192 星子集分类一致; 24,883,200 个 FITS float32 样本完全一致。 此处测试的是保留的生产路径;tile 原型的 double 正确性由回放验证,不冒称已接入 renderer。
make -j1 test通过(33.44 s)。
保留三类早期非零退出:沙箱未暴露 GPU、v2 分散输入的 scratch 超限、读取器误拒绝合法 wing-clipped support。后者的修复保留 event 的物理 support,仅在实际遍历时限制 cache 范围。 未删失败日志,未在任何失败后不加分析自动扩大测试规模。
最小复现
从仓库根目录先按 build_commands.txt 构建。 固定输入已随报告保留;原大 catalog/lens map hash 在 manifest。已有日志拒绝覆盖,重复 运行请使用新标签和新的事件输出路径:
python3 benchmarks/hip_psf_replay_2026-09-07/run.py repeat_capture 60 \
build/Release/capture_psf \
output/lens/schwarzschild_galactic_center_R100_45deg_16_4_4k_.grlens \
benchmarks/hip_psf_replay_2026-09-07/center.csv \
0 130882 65536 /tmp/gr-psf-repeat.events 1e13 1e8 0 0 2
python3 benchmarks/hip_psf_replay_2026-09-07/run.py repeat_atomic 45 \
build/Release/replay_psf /tmp/gr-psf-repeat.events 65536 atomic
python3 benchmarks/hip_psf_replay_2026-09-07/run.py repeat_tile16 45 \
build/Release/replay_psf /tmp/gr-psf-repeat.events 65536 16
python3 benchmarks/hip_psf_replay_2026-09-07/run.py repeat_tile32 45 \
build/Release/replay_psf /tmp/gr-psf-repeat.events 65536 32
以上是重跑示例,repeat_* 标签本次未执行;实际执行命令逐条保存在各原始日志。