高温氦气物性补全;三通四通能量计算bug修正
This commit is contained in:
1 parent
6fc9afe41d
commit
2b07d996cf
133 files changed
+5230
-253310
No files matched your search
@@ -0,0 +1,71 @@
|
||||
# 结果存储额度增量优化验证 — 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% 的总耗时降幅。本次没有改动求解器的数学计算路径。
|
||||
|
||||
复现:
|
||||
|
||||
```powershell
|
||||
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` 完整依赖环境运行:
|
||||
|
||||
```powershell
|
||||
$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 语法检查通过。
|
||||
Reference in new issue
Block a user