性能:MPQ 离线烘培管线性能瓶颈分析与并发加速改造(MPQ Offline Baking Pipeline Acceleration) #396
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
问题背景与现状瓶颈分析 (Root Cause Analysis)
在暗黑破坏神 II (v1.13c) Web 端引擎的资产管线中,为了消除浏览器端运行时对
d2data.mpq/d2char.mpq/d2exp.mpq的沉重 HTTP Range 请求与纯 JS 即时解压成本,通过scripts/pack-act-assets.ts与scripts/pack-entity-assets.ts在离线阶段将全量关卡场景与实体动画烘培为 Web 原生索引 PNG 与scene.json。然而,目前全量执行
npm run pack:data(烘培 136 个关卡、365 个地图场景及数十种怪物实体动画)耗时长达 15~25 分钟。经多维度性能剖析与基准测量,定位到以下核心瓶颈与性能放大器:pack-act-assets.ts采用单一的for (const entry of LEVELS)串行循环。pack-entity-assets.ts虽然声明了 6 个workersPromise,但在 Node.js 默认单主线程机制下,DCC 解码和 COF 拼帧等 CPU 密集型任务只能交替排队,实质上仍运行在单核上(整体 CPU 利用率仅约 4%)。pack-act-assets.ts中硬编码了LIBRARY_CACHE_LIMIT = 16。由于单个大关卡往往需要加载 10~15 个 DT1,关卡切换时缓存被频繁淘汰冲刷,导致通用底包(如Blank.dt1,InvisWal.dt1,Warp.dt1,Town.dt1)和公共地块被重复从 MPQ 读盘、解压并执行纯 JSdecodeDt1上千次,白白浪费 3~5 分钟。scripts/png.ts每一行像素均用纯 JS 评估 3 种滤波得分,且采用了同步最大压缩deflateSync(raw, { level: 9 })。在单线程下累计耗时达 2~3 分钟。decodeDt1在尝试候选 offset 时频繁分配new Uint8Array(tileWidth * tileHeight)并用decoded.some(...)进行全数组扫描。优化方案规划 (Solutions 1, 2, 3)
方案 1:扩大 DT1 全局常驻缓存(Zero-Risk Quick Win)
pack-act-assets.ts中的LIBRARY_CACHE_LIMIT从 16 提高至300(或完全常驻),确保所有 242 个唯一 DT1 仅解码一次并终身缓存。方案 2:优化 PNG 压缩管线与滤波算法
deflateSync压缩等级由level: 9调至官方平衡档level: 6(压缩率差异 < 2%,压缩速度快 3~4 倍)。方案 3:多进程 / Worker 并发架构改造
pack-entity-assets.ts)同样采用多 Worker 进程并行处理 68 个怪物 spec 与角色的 DCC/COF 拼帧与 PNG 输出。验证与验收标准 (Acceptance Criteria)
npm run verify:packs、npm run verify:bundle-no-mpq、npm run verify:entity-packs全部 100% 通过。优化落地与端到端实测验证报告 (Verified & Closed)
针对 MPQ 离线烘培管线性能瓶颈,方案 1、2、3 已全部落地并通过独立 Victory 审计员三阶段严格终审:
一、 核心改造内容
LIBRARY_CACHE_LIMIT扩至 256,完整常驻全游戏所有 242 个独立 DT1 库,彻底消除了 1,651 次关卡引用中的全部 903 次缓存震荡与重复解包解码。deflateSync压缩等级由level: 9调至平衡档level: 6;scripts/pack-act-assets.ts:落地 Node.jsworker_threads动态工作池,打满宿主机 24 核心并行烘培全量 365 个地图场景;scripts/pack-entity-assets.ts:将单线程 async 假并发重构为真多核并发,并行处理 69 个怪物与角色动画合成;.tmp+rename),并顺手修复了 Schema 2char-so.json中walk/stand别名索引的已知缺陷。二、 实测基准与测试大盘
npm run verify:packs:1,795 / 1,795 项断言全部 100% PASS(284 MB 像素数据逐点无损);npm run verify:entity-packs:100% PASS(全 5 幕 68 种怪物与 7 职业图集逐一核对);npx tsc --noEmit0 错误;index.json的 SHA256 与单线程基准 100% 逐比特一致。全量验收标准均已满足,Victory 审计通过。