BetterAutoSave v0.16.0-beta.1 — Forge 1.20.1 异步存档优化
Pre-release
Pre-release
·
67 commits
to main
since this release
v0.16.0-beta.1 — 异步 POI 预读(Tier A,加载侧性能)
本版在 v0.15 异步加载的基础上,把区块加载时的 POI region 读盘从主线程挪到后台 load worker。异步加载开启后,这段 POI 读盘等待是主线程上最大的剩余开销;本版将其基本清零。功能随异步加载自动生效,仅 Forge 1.20.1 构建。异步加载本身仍默认关闭、需手动开启
这是什么
- 异步加载(PARTIAL 模式)把区块反序列化搬到后台,但
PoiManager.checkConsistencyWithBlocks(POI 一致性校验)仍回主线程回放,而它触发的 POI region 读盘让主线程在tryRead().join()上同步阻塞等磁盘 - spark 实测:高速移动 / 大视距下,这段 POI 读盘等待是异步加载开启后主线程的头号剩余开销
- 本版让 load worker 在反序列化那一刻顺手把该列 POI region 字节读出后台,主线程回放前用预读字节填好 POI 缓存,随后的一致性校验直接命中缓存、不再读盘
实测效果
- 生产服真机(137 mod 重整合包,8 load worker,高速飞行):主线程 POI
getOrLoad从 15.0% 降到 0.1%,那段同步读盘等待清零,主线程区块加载开销净降约 13.7% - TPS 满,零解析回退,POI 数据零偏差
配置([load] 段)
load.asyncPoiPrefetch(默认 true,可热重载):是否在 load worker 上预读 POI region。仅当异步加载开启(load.enabled=true)且模式为 PARTIAL 时生效。设 false 回到主线程同步读 POI(vanilla 行为),作 POI 存储相关 mod 异常时的兜底
安全与兼容
- 线程安全:worker 只触底层 IOWorker(线程安全),绝不碰非并发的 POI 缓存;POI 缓存的解析与写入全部留在主线程回放,与所有其它 POI 访问同线程序
- 不丢数据:预读到的是该列已存档的 POI 字节,主线程解析填缓存与 vanilla
readColumn逐字等价;若该列在回放前已被加载,跳过预读字节、以活数据为准 - 失败兜底:POI 预读失败不影响区块加载,自动退回主线程按 vanilla 读 POI
- 在线区块回退路径不预读(回退的是已加载区块,POI 多在内存,预读会被护栏跳过而浪费)
为什么仍标 beta
- Tier A 是异步加载的加载侧增强,异步加载本身仍在公测、默认关闭;本版随同标记预发布
- 已真机验证主线程开销清零、零丢数据信号,但多人长时间并发的稳态仍在持续观察
升级
- 替换 jar 即可。未开启异步加载(
load.enabled=false,默认)的用户:本版无任何行为变化 - 已开启异步加载的用户:Tier A 默认自动生效(
asyncPoiPrefetch=true),无需额外配置;要关闭设asyncPoiPrefetch=false