Files
SystemSimulationApp/docs/other/结果存储额度增量优化验证-2026-09-15.md
T

5.8 KiB
Raw Blame History

结果存储额度增量优化验证 — 2026-09-15

问题与范围

原生端每次准备写入状态块时,先通过 storage-reserve 申请状态块与后续输出块的合计额度,并同步等待 Python 回复。旧版 ResultArchive.reserve() 每次都遍历历史目录、统计大小、读取完整 manifest、检查使用锁和工作进程,再序列化、fsync 并原子替换当前 manifest。因此,块数、历史工程数量和历史清单体积一起放大了求解器的等待时间。

这里的重复扫描是历史目录和清单的配额检查,并非每块都重新读取历史二进制轨迹做 CRC。结束时的一次完整性扫描仍保留。

修改

  • 使用预先持久化的额度窗口:最大 16 MiB,同时不超过总配额的 1/16;单块需求超过窗口时按实际需求申请。
  • 窗口内逐块扣减本实例的剩余额度,不访问历史目录、不拿跨进程配额锁、不写 manifest。
  • 剩余额度不足时,在原有全局锁下只为缺少的部分确保空间,再利用已有空闲空间适量预留。不会为了扩大窗口而额外淘汰历史记录。
  • 额度先原子持久化、后允许工作进程写入。未消费的额度仍被其他进程计入占用,避免重复分配;发布失败不发放新额度。
  • 实例内加锁,防止同一归档的并发扣减丢失。结束时归还未使用的窗口额度,关闭后拒绝继续申请。
  • 原有使用锁、孤儿工作进程保护、未知文件不删除、配额耗尽返回部分结果以及 CRC 校验保持。

额度窗口只是记账,不会增加同等大小的内存缓冲或预写空文件。历史目录在创建归档及额度补充时仍会扫描,并非完全消除了历史数量的影响;磁盘空间紧张时,窗口缩小,收益也会降低。多个同时运行的工程可能暂时各占用一部分未消费额度,因此窗口设置了上限。本机制是应用内逻辑字节配额,不是操作系统硬配额,也不能防止用户从外部工具额外写入或删除文件。

不修改二进制格式、采样点、求解算法、求解容差或结果传输格式;不新增数据库、不迁移或清理用户的已有结果。

性能对比方法

脚本:tests/manual/benchmark_result_reservations.py。旧路径仅作为脚本内对照函数保留,生产代码使用新路径。所有历史目录、清单及结果文件都在独立临时目录中生成。使用真实文件系统、锁和 fsync,不模拟 I/O。

环境:Windows、本机 Python 3.12。每组两轮,下面为算术平均值;运行时间会受系统缓存、磁盘及其他进程影响。额度微基准的清单包含 1,000 个变量,历史文件是只用于目录/大小统计的合成夹具,不是完整真实工程。计时不包含夹具创建、归档初始化和结束扫描,也不包含求解与实际数据块写入。

历史记录数 申请负载 旧路径耗时 新路径耗时 检查/清单发布次数(旧 → 新)
0 256 × 64 KiB 2.294 秒 0.00844 秒 256 → 1
100 256 × 64 KiB 52.247 秒 0.22886 秒 256 → 1
300 256 × 64 KiB 161.104 秒 0.57988 秒 256 → 1
0 64 × 1 MiB 0.639 秒 0.04084 秒 64 → 4

以上是额度管理耗时,不可直接解释为整段仿真的提速比例。64 MiB 场景覆盖多次窗口补充。

实际原生仿真对比

机械质量块连接两个自由端口,RK45,仿真区间 0–1 秒,采样步长 0.00001 秒,共 100,001 点;结果目录内有 300 条合成历史记录。共用同一次编译产物,计时包含归档初始化、工作进程、写块、结果读取和结束校验,不包含编译和历史夹具创建。每种路径两轮。

路径 第 1 轮总耗时 第 2 轮总耗时 平均总耗时 平均额度申请耗时
逐块全量检查 32.077 秒 28.035 秒 30.056 秒 29.085 秒
批量额度 1.458 秒 1.421 秒 1.440 秒 0.565 秒
  • 每次仿真都有 98 次块额度请求;新路径只补充两次窗口。
  • 包括初始化在内,目录配额检查由 99 次降至 3 次;包括初始化、工作进程登记和结束在内,清单发布由 101 次降至 5 次。
  • 四次运行的 states.bin、outputs.bin SHA-256 完全一致,返回的每个采样值也完全一致,CRC 检查通过。
  • 这是一组求解计算较轻、便于暴露存储等待的模型,不代表所有复杂工程都能获得约 95% 的总耗时降幅。本次没有改动求解器的数学计算路径。

复现:

py -3.12 -m tests.manual.benchmark_result_reservations --native
py -3.12 -m tests.manual.benchmark_result_reservations --histories 0 --requests 64 --block-kib 1024 --repeats 2

正确性回归

新增窗口快速路径无文件系统操作、跨窗口只申请差额、临近配额不额外淘汰、发布失败回滚、八线程并发扣减、关闭后拒绝申请、结束归还额度、跨进程未消费额度保护、申请失败后仍可写入更小尾块等回归。

原生测试同时覆盖 RK45/BDF、多块及尾块、所有输出的 binary64 位一致性、负零、取消、强制终止、配额耗尽和存储 I/O 失败。

使用项目已有 .venv-win 完整依赖环境运行:

$env:SIMULATION_NATIVE_REQUIRE_TOOLCHAIN='1'
./.venv-win/Scripts/python.exe -m unittest tests.test_result_storage tests.test_native_sample_storage tests.test_native_cache_storage tests.test_native_result_transport tests.test_result_csv_export -v

共 56 项,53 项通过,3 项因 Windows 缺少创建符号链接的权限而跳过;没有失败。传输流、取消后的部分结果和 CSV 导出契约也通过。单独使用系统 Python 跑后两组时缺少 FastAPI,随后已切换上述项目环境完成全部五组验证,未安装或更改依赖。Python 语法检查通过。