Files
SystemSimulationApp/docs/other/八路模型计算效率与网页阶段计时-2026-09-11.md
T
lujingze 3bc4be3c06 优化原生结果编码传输与浏览器缓存,记录八路性能基线
原生结果series通过字节索引直传,C端使用Ryu精确回读编码和64 KiB批量写出;网页采用Float64缓存和CSV工作线程,减少结果处理与保存等待。

补充八路AME曲线核查、全流程分阶段计时、独立编码基准和复现工具,固定后续优化采用修正八路及rtol=1e-8。C写出1.1808→0.1638 s,点击到可查看8.0100→6.9756 s。

验证:最终10项编码专项、29项相关后端回归通过;8份原生结果逐位一致,16次网页结果/CSV/刷新恢复通过。前端构建及缓存/CSV专项在本轮结果处理工作中通过。环境、原始大结果与临时构建不纳入Git。
2026-09-11 15:09:15 +00:00

22 KiB
Raw Blame History

八路模型计算效率与网页阶段计时(2026-09-11)

本轮以 808c484 的正式代码和 test-mql-8-corrected.json 为主案例。八路在当前默认精度下完整运行,未退回四路。本轮增加独立诊断脚本和运行记录,没有修改生产算法、工程参数或输出采样。后续遵循 八路优先的优化验证约定。

运行范围与可复现条件

  • 工程 SHA256:670977bef67e62d9c66e8af497bada208bd72a7301be45128d185d47282cf288;CLI XML SHA256:2804b33f04cabb3c10fcc3cc0843c35de17efbe1b6ee5e5e821edd9a5515a23d。对应 AME 为 tests/data/test_mql.ame,SHA256 1ff0ea4284b9248260eeceb8b27cd0bc14dbccb43554ab8c0b49900d0b944c3d。
  • 157 元件、178 条连接、132 连续状态;返回 1784 个变量、1002 个原始采样点(含事件点),仿真 0~10 s,输出间隔 0.01 s。
  • CVODE BDF / SUNDIALS 7.4.0,rtol=1e-8,max_step=1e30;自动首步。实际绝对误差限按状态生成:质量 1e-14 kg、内能 1e-8 J、速度 1e-12 m/s、位移 1e-12 m,并非对所有状态统一使用配置对象中的 atol=1e-8。数值雅可比、稠密线性求解和事件处理策略保持生产设置。
  • Linux x86_64 虚拟机,Intel Xeon Silver 4210R @ 2.40 GHz,16 逻辑 CPU、约 30 GiB 内存;GCC 13.3.0、Python 3.12、Node 24.18.0、Chromium 151.0.7922.34。原生进程主要为单核计算,环境与构建哈希保存在原始记录。
  • 各组预热一次、正式运行三次;中位数与范围单列。三算法组交错执行;网页对照组与分阶段插桩组串行执行,不同时运行诊断求解、绘图或大编译。样本数较少,组间百分之几的差异不作为显著优化结论。

管流算法效率与触顶情况

三算法使用同一 corrected 八路、物性复用实现和全系统积分精度。固定点版本仅在明确的 5d5a2e1 基线上恢复原半步松弛管流循环,其余生产数值逻辑保持一致;不是运行旧版整个应用。前次牛顿取自该提交,当前保护牛顿取自本轮正式内核。此组没有逐次调用计数插桩。

算法 纯求解中位数(范围)/ s 进程全程中位数 / s RHS 次数 接受 / 拒绝步
旧固定点,16 / 64 轮上限 12.0976(11.9926~12.1511) 14.2514 119058 9647 / 679
前次牛顿 5.8183(5.7829~5.8944) 7.9144 74265 6974 / 454
当前保护牛顿+二分回退 5.9138(5.9115~5.9323) 7.9698 74265 6974 / 454

相对旧固定点,当前纯求解时间减少 51.12%、速度约 2.05 倍,进程全程减少 44.08%,RHS 次数减少 37.62%。相对前次牛顿,本组耗时增加约 1.64%,不能宣称保护机制带来额外提速;两版牛顿的完整采样、最终输出和状态逐值相同。

另用未经本轮插桩的正式构建独立运行一次预热、三次正式检查:纯求解中位数 5.7972 s(5.7897~5.8214),进程全程 7.8504 s(7.8437~7.8685),均完成 10 s;每次 RHS 74265、接受 6974、拒绝 454、雅可比 475、线性分解 1656、状态转换 1、求解器启动 4。该组构建缓存命中,输入准备 0.1493 s、构建/缓存核验 0.03294 s;这些准备时间在三个进程运行前发生一次,不包含在纯求解时间内。单独组的 5.80 s 不与上一组旧算法拼接计算加速比。

为区分算法本身和积分轨迹变化,另对三版内核进行独立计数诊断:先各自跑完整八路,再将当前轨迹的 3,081,320 组实际管阻方程输入全部原样重放给三个版本,不抽样、不去重。诊断耗时不用于上述性能比较。

同一组管阻输入的计数 旧固定点 前次牛顿 当前保护牛顿
解析返回 / 迭代求解 0 / 3081320 2370685 / 710635 相同
累计循环轮数 49431317 3081555 相同
单次最多轮数 64 6 6
进入最后允许轮次 3037792(98.587%) 0 0
耗尽额度且未满足各自停止条件 3010570(97.704%) 0 0
实际返回值的统一相对残差 > 1e-9 3072455 0 0
二分回退 / 非有限返回 0 / 0 0 / 0 0 / 0

牛顿累计轮数减少 93.766%。710635 次迭代调用分别用 3 轮 74290 次、4 轮 361601 次、5 轮 236183 次、6 轮 38561 次。当前案例没有触发二分或失败路径,所以它验证了正常输入的效率和一致性,不能代替极端状态下的保护测试,也不能证明任意系统必然收敛。

“进入最后一轮”与“耗尽仍未满足条件”分开统计:固定点 PNL00R 的 64 轮分支有 1638 次进入最后一轮、但没有耗尽失败;真正耗尽的都来自其他管路的 16 轮分支。旧循环满足自身停止条件的 70750 次中,61885 次仍不满足当前统一方程残差门槛;相对残差超标不直接代表同等数量的大绝对流量误差。

各自完整积分轨迹上,旧固定点实际管阻调用 5041645 次、耗尽 4937544 次;两版牛顿均为 3081320 次、耗尽 0 次。零压差 247634 次和 PNL00R 直接层流 235766 次另计,未混入混合摩擦方程残差。当前插桩结果与独立正式构建的 series/final/finalState 逐值相同。

该八路在积分 RHS 中请求管流缓存 2970600 次,命中 0;另有 594120 次直接调用。物性复用与这项管流缓存不同;此结果只说明本例可进一步评估缓存查找的成本,不能直接推广到其他拓扑或据此删除缓存。

真实网页主流程与额外操作成本

使用正式 Vite 静态构建,经 Playwright 驱动 Chromium;无模拟 API、预制结果注入或重复读取响应体。独立对照服务 127.0.0.1:8013 不加载诊断插桩;分阶段服务 127.0.0.1:8012 仅在隔离 C 主程序中增加稀疏时钟,并包装实际后台函数。两个服务的求解器和元件文件逐字节相同,前端构建集合 SHA256 同为 2faa6ce32ee9997187870d64af2bc235a830eb7b8def7749ddcb0eaeeed4831e;计时脚本 SHA 也相同。

每组预热一次、正式三次。每轮从公开 JSON 导入入口加载同一 corrected 文件,公开导出工程后逐项验证全部参数、端点和仿真设置,然后点击运行;导入与核查不包含在点击运行计时中。每轮继续打开结果页、选择指定管路温度、下载 CSV 与结果文件,再刷新并核对恢复结果。结果页和温度曲线立即打开,允许浏览器 IndexedDB 异步保存与查看过程自然重叠。

下表单位为秒,格式为 中位数(最小~最大)。对照组是常规网页成本的主记录;“首次绘制机会”指可见 DOM 后经过两次 requestAnimationFrame,未测量 GPU 完成时间。

阶段 对照组 / s 分阶段组 / s
工程导入 change → 画布首次绘制机会 0.2527(0.2273~0.2862) 0.2312(0.2251~0.2411)
点击运行 → 完成状态 DOM 9.8716(9.7697~9.8826) 9.7777(9.7358~9.8408)
点击运行 → 完成状态首次绘制机会 9.8989(9.7840~9.9104) 9.8005(9.7596~9.8660)
点击运行 → 结果页首次绘制机会(自动切页) 10.1516(10.0600~10.1834) 10.0589(10.0305~10.1056)
点击运行 → 温度曲线首次绘制机会(自动选曲线) 10.6899(10.5762~10.7431) 10.6160(10.5916~10.6433)
点击运行 → 观察到 IndexedDB 保存完成指针 12.2922(11.8303~12.4076) 12.4344(11.5322~12.4967)
进入结果页 → 首次绘制机会 0.1910(0.1893~0.1980) 0.1927(0.1832~0.1946)
选择温度 → 曲线首次绘制机会 0.0269(0.0262~0.0297) 0.0276(0.0233~0.0293)
CSV 点击 → 下载并保存 5.6198(5.5717~5.6381) 5.5732(5.4253~5.6625)
结果文件点击 → 下载并保存 1.2308(1.2265~1.3213) 1.2921(1.1552~1.5145)
刷新导航 → 已恢复结果首次绘制机会 0.5885(0.5406~0.6592) 0.5487(0.5074~0.5630)

无插桩对照组的 C 纯求解中位数为 6.0653 s、进程全程 7.9499 s;独立 CLI 的 5.7972 s 属另一运行环境下的分组结果,不把差值直接归因于网页某项 CPU 工作。分阶段组点击到完成绘制为 9.8005 s,对照为 9.8989 s,相差约 -0.99%;本组三次样本未见明显端到端插桩增量,也不能把该负差当作加速。持久化和导出波动更大,逐次原始值均保留。

初次导航只记录每组一次:HTML loadEventEnd 对照 0.0971 s、分阶段 0.1086 s;Playwright 观察到工程导入控件时分别为 0.5628 / 0.6064 s,包含自动化观察与调度延迟,不是严格的首次可交互时间。首次工程导入到两帧观察点,对照预热为 0.3716 s;三次重复导入中位为 0.2527 s。页面加载、导入、仿真、查看与导出分别记录,未用自动化操作间隙拼成一个“纯网页耗时”。

“DOM 稳定”另取 120 ms 无变动再等两帧:结果页中位 0.3710 s、温度曲线 0.1736 s、刷新恢复 0.7575 s(对照)。这包含人为安静窗口,不能把它全称为渲染工作。下载完成包含 Playwright 通知、saveAs 与文件系统开销,不等于浏览器内序列化 CPU 时间。

后台内部各阶段

用每个请求的 X-Simulation-Id 将网页与后台记录一一关联。下表为分阶段组正式三次的秒数;所列主要阶段在单个请求内依次发生。各阶段分别取中位数,故其相加不保证等于总耗时中位数。

阶段 中位数(最小~最大)/ s
XML 校验 0.0231(0.0222~0.0246)
网络编译 0.0364(0.0361~0.0465)
系统 C 代码生成 0.0542(0.0528~0.0548)
构建缓存核验(3 次均命中) 0.0321(0.0308~0.0331)
C 参数准备 0.0000503
C 初始化与初始采样 0.0001(0.0001~0.0001)
C 纯积分 6.0855(6.0414~6.0994)
C 最终采样/状态处理 0.0000029
C 最终及全采样输出投影 0.0855(0.0837~0.0861)
C 结果 JSON 格式化并写文件 1.1707(1.1656~1.1945)
Python 读文件并 UTF-8 解码 0.0360(0.0321~0.0429)
Python 解析原生 JSON 0.5513(0.5429~0.5588)
进程启动/等待/退出等未细分余量 0.0029(0.0025~0.0029)
结果接口元数据组装 0.0330(0.0245~0.1175)
最终 NDJSON 结果事件序列化 1.1928(1.1862~1.2106)
序列化结束 → ASGI 最后响应体发送完成 0.1715(0.1489~0.1808)
HTTP 其余编排/调度余量 0.0124(0.0114~0.0155)

后台 HTTP 全程中位 9.5123 s(9.4458~9.5845)。内部 C main 全程 7.3380 s,Python 原生执行与结果读取包装 7.9194 s,仿真 worker 全程 8.1380 s;这些是包含上表子阶段的父区间,不能再次相加。ASGI send 的累计 await 为 0.0701 s,可与生成结果的后台任务重叠,亦不代表客户端网络总时间。诊断产物保留另耗约 0.00066 s,已包含在原生执行包装中。

约 2.95 s 用于 C 的 JSON 写出、Python 读取解析及 HTTP 结果 JSON 序列化,约为后台总程的 31%;相比之下输出物理量投影仅约 0.086 s。这里先定位到文本结果处理成本,并未将整个差额笼统归为物性或求根。

正式网页八次运行均复用已构建的程序。唯一冷构建来自功能预检:编译/核验 3.4154 s,构建键 bcb85b5dce729fe9b7a503919b720be03950ff31839877edd344377d4ee9cfc0 与后续完整八路分阶段组相同;预检将运行终点设为 0.02 s,只改变运行时选项,未改变编译出的系统程序。这个单次冷编译时间可供首次运行成本参考,但本轮没有测得完整 0~10 s 的冷启动网页总时间,不把预检总时间冒用为正式结果。

浏览器内部、持久化和导出细分

分阶段组保留了原始 fetch、流读取、解码、JSON.parse、IndexedDB 事务和下载锚点的时间戳,没有克隆响应或重复解析。

观察区间 中位数 / s 含义与边界
点击运行 → 调用 fetch 0.0234 含前端模型检查、快照/XML 和提交准备,未单独计 XML CPU
fetch → 收到响应头 0.0298 收到流式响应头,不表示仿真已经算完
响应头 → 读到流 EOF 9.6765 包含后台计算、传输、消费者处理与调度
累计未完成的流 read 等待 9.4636 含后台结果尚未生成的等待,不能称为纯网络时间
最终结果的原始 JSON.parse 0.1125 同步解析仅执行一次
全部流消息 JSON.parse 0.1139 已含上一行
UTF-8 decode 累计 0.0280 原始解码调用,不包含分片扫描/拼接
最终 JSON.parse 结束 → 完成 DOM 0.0430 含应用处理和 React 调度,未独立测 React CPU
结果解析结束 → IndexedDB 完成指针发布 2.6279 含批处理、事务等待与调度,可与看图重叠
首次保存事务 → 完成指针发布 2.5952 仍是异步区间;不是磁盘或主线程独占时间
CSV 点击 → fetch 0.2641 包含将整份结果再次 JSON.stringify 的提交准备
CSV fetch → 响应头 4.6968 含浏览器请求准备、后台处理及网络/调度
CSV 点击 → Blob 下载锚点 5.0143 浏览器已经取得并准备好下载数据
结果文件点击 → Blob 下载锚点 0.6113 包含结果文件序列化及 Blob 准备

最终流式响应约 33.73 MB;原生结果 JSON 为 32,725,293 字节,CSV 为 32,346,795 字节,结果文件约 33.85 MB(十进制 MB)。本次是本机回环 HTTP,未模拟远端带宽、TLS 或网络延迟;不能把这些网络相关耗时直接推广到远端部署。

CSV 后台另有独立请求,按请求顺序和时间戳关联,正式三次分段如下:

CSV 后台阶段 中位数(最小~最大)/ s
ASGI 开始 → 收完请求体 0.0262(0.0247~0.0285)
收完请求体 → CSV 函数开始 0.7072(0.7010~0.7138)
CSV 校验、逐单元格式化与文本组装 2.3684(2.3616~2.3885)
CSV 函数结束 → HTTP 完成 0.1252(0.1221~0.1264)
CSV HTTP 全程(父区间) 3.2264(3.2177~3.2494)

“收完请求体→CSV 函数”约 0.707 s,涵盖路由层 JSON 解码、模型校验及调度,未再将每项 CPU 时间拆开。CSV 浏览器 fetch 到响应头比 ASGI 全程更长;跨进程请求准备、发送及调度的余量未进一步归因。CSV 的完整结果往返及文本组装成本已经实测,后续可据此单独优化。

本轮验证与下一步优先级

两组共 8 次网页运行均完成 10 s,且无 pageerror。每轮公开导出的工程参数与连接全部匹配固定输入;结果页、精确单位 K 的温度曲线、CSV、.simresult 下载和刷新恢复均通过。8 份 CSV 均为 1785 列 × 1002 数据行,合计 14,308,560 个数值单元与独立原生结果精确相等;全部 series/final 也精确相等,刷新前后完整结果一致。4 份后台稀疏插桩原生文件的 series/final/finalState 均与生产文件逐值相同。56 个唯一气体质量状态用 math.fsum 汇总,初始总质量 5.566893015 kg,最大漂移 1.15463e-14 kg;所有保存数值有限。

初次自动化预检曾误用旧控制台 CSS,另一次重复组在刷新后假定建模工程自动恢复而未提交新请求。这两类脚本失败保存在 browser-stage-smoke/ 与 browser-control-failed/,明确排除正式统计。最终脚本使用当前 DockedSimulationConsole、每轮重新导入并核对工程,两个完整正式组均通过。0.02 s 的功能预检只证明操作流程,不混入八路完整计算效率。

依据本轮数据,后续优先考虑:

  1. 先追踪八路早期压力/温度差和碰撞事件输出。 参数对齐与局部求根成功不能代替整条曲线正确性;保留八路主案例,继续固定当前输入与精度。
  2. 减少结果反复文本化。 当前 C 写 JSON、Python 再解析、HTTP 再序列化合计约 2.95 s;优化这条路径时仍需保留全部变量、采样、浮点数值与输出合同。
  3. 单独优化 CSV 与浏览器持久化。 CSV 全量回传后台并组装文本明显影响使用时间;持久化约 2 s 以上、且与查看曲线重叠,适合分别评估批大小、复制与调度,不能把保存等待计为绘图耗时。
  4. 继续剖析 RHS/雅可比等求解成本。 管流触顶已经为零,当前再削减迭代上限没有实测依据。可先评估本例零命中的管流缓存和 74265 次 RHS 的组成;更改雅可比或缓存策略后仍按同一八路、同精度和完整输出复核。

八路算法与网页阶段耗时

图中三算法与浏览器操作取三次中位数;后台堆叠图选 HTTP 总耗时居中的单个请求,所有片段可相加。浏览器各操作区间不能相加;完整可缩放图为 SVG。

与当前 Amesim 归档的对照

本次找到可用的八路保存曲线。独立核对当前 AME 内的图纸、参数数据、编译 C、状态与变量索引及初值,未发现此前四路归档中那种图纸/缓存错配;完整说明见 当前八路归档与曲线核查。使用的是当前 AME SHA,未套用绑定另一归档的历史八路冻结基准。

选取全部 132 个连续状态对应的压力、温度、位移与速度,另加阀流量、接触力、限位力和间隙,共 176 条曲线;明确映射表压/绝压、SI 单位与接口方向,分别在双方原始保存网格上线性插值对照,不删去原生事件点。下表为 AME 保存网格上各类最差曲线的最大差及该曲线 RMS,不是把全类所有点混算的 RMS。

量 最大绝对差 对应曲线 RMS
压力 163395.189 Pa 7170.441 Pa
温度 105.215279 K 5.829065 K
阀质量流量 0.002990901 kg/s 0.000114014 kg/s
接触力(AME 保存网格) 5131.971 N 225.218 N

最大压力、温度和此表接触力差在 0.01 s,不能全归因于后续碰撞采样时刻不一致。原生另有 t=0.9833956321732664 s 的原始事件点,8 个接触力约 4.035×10¹¹ N;AME 只保存相邻 0.98 / 0.99 s 点,无法据其线性插值判断 Amesim 精确事件时刻或是否也有极窄峰。当前 AME 的 UD00 输入含 1e17 初始信号,双方公共质量元件都出现极大位移/速度,也不能把“数值有限”当成物理合理性证明。本轮未修改这些 AME 参数。

因此,八路运行与计时记录完成,不等于八路曲线一致性验收通过。目前没有八路专用接受阈值,也缺少足够密的 AME 事件输出;保留差异供后续核查,不为通过而放宽门槛或换四路。

Amesim 耗时对比跳过:当前环境没有可调用的 Amesim,归档也没有可信 CPU/墙钟记录;.ameperf 中的时间是仿真事件时刻。归档名义容差为 1e-7,本轮为 1e-8,也不能冒称同精度速度比较。没有重跑 Amesim,没有从 10 s 仿真终点或文件时间戳推算耗时。

记录、脚本与复现

所有输入快照、编译程序、完整曲线、下载文件和浏览器截图都放在 Git 忽略目录 test/,环境仍在 .venv/native/,未纳入 Git。报告引用的相对路径在仓库本地可打开;这些大型运行产物不随 Git 克隆传递。

# 八路三算法基准;目录必须为新目录
.venv/bin/python tests/manual/benchmark_native_pipe_solver.py \
  tests/data/test-mql-8-corrected.json --output-dir test/new-mql8-variants --runs 3

# 正式构建独立基准
.venv/bin/python -m app.simulation.native_codegen tests/data/test-mql-8-corrected.json \
  --output-dir test/new-mql8-production --runs 3 --timeout 120

# 后台阶段记录服务;需要已有 frontend/dist,选空闲端口
.venv/bin/python tests/manual/backend_stage_profile.py \
  --output-dir test/new-mql8-backend --port 8012
# 另一个终端:--plain 为无诊断插桩的对照服务
.venv/bin/python tests/manual/backend_stage_profile.py --plain \
  --output-dir test/new-mql8-control --port 8013 \
  --frontend-dist test/new-mql8-backend/frontend

# Chromium 所需依赖仅使用仓库现有忽略环境
export LD_LIBRARY_PATH="$PWD/.venv/native/browser-libs/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
.tools/node-v24.18.0-linux-x64/bin/node tests/manual/browser_stage_profile.mjs \
  --output test/new-mql8-browser-control --url http://127.0.0.1:8013 --mode control --runs 3
.tools/node-v24.18.0-linux-x64/bin/node tests/manual/browser_stage_profile.mjs \
  --output test/new-mql8-browser-profiled --url http://127.0.0.1:8012 --mode profiled --runs 3