Faster roof scan and heat pass with identical results (t21)
- The roof is rescanned only in area columns that changed since the last scan: a quiet Huge world goes from 4.60 to 1.88 ms per scan (every 20 ticks). - The heat pass skips react() for solids and powders below their first reaction threshold: Huge world digging 2.54 -> 2.34 ms/tick, quiet 1.39 -> 1.18. - Every suite's output is identical apart from timing lines; seeds make the same worlds. - test/t_sim_optimizations.js checks the dirty roof against a full scan and the heat loop against the reference loop byte for byte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
// Reference heat loop before t21 phase 3; preserves conduction and Float32 store order.
|
||||
function referenceHeatChunk(c, sc) {
|
||||
const cx = c % CW, cy = (c / CW) | 0;
|
||||
const x0 = cx << 5, y0 = cy << 5, x1 = Math.min(W, x0 + 32), y1 = Math.min(H, y0 + 32);
|
||||
const leftCold = cx > 0 && !hot[c - 1], upCold = cy > 0 && !hot[c - CW];
|
||||
let maxDev = 0, burning = false;
|
||||
for (let y = y0; y < y1; y++) {
|
||||
const amb = AMB[y], yw = y * W;
|
||||
const dDown = y + 1 < H ? amb - AMB[y + 1] : 0, dUp = y > 0 ? AMB[y - 1] - amb : 0;
|
||||
for (let x = x0; x < x1; x++) {
|
||||
const i = yw + x;
|
||||
if (x + 1 < W) condPair(i, i + 1, sc, x + 1 === x1 ? c + 1 : -1, 0);
|
||||
if (y + 1 < H) condPair(i, i + W, sc, y + 1 === y1 ? c + CW : -1, dDown);
|
||||
if (x === x0 && leftCold) condPair(i - 1, i, sc, c - 1, 0);
|
||||
if (y === y0 && upCold) condPair(i - W, i, sc, c - CW, dUp);
|
||||
let m = mat[i];
|
||||
const ph = PH[m];
|
||||
let t = temp[i];
|
||||
let rel;
|
||||
if (ph === PH_EMPTY || ph === PH_GAS) {
|
||||
if (y > 0) {
|
||||
const u = i - W, pu = PH[mat[u]];
|
||||
const ex = (t - amb) - (temp[u] - AMB[y - 1]);
|
||||
if ((pu === PH_EMPTY || pu === PH_GAS) && ex > 2) {
|
||||
const a = ex * (sc > 1 ? 0.45 : 0.25);
|
||||
t -= a; temp[u] += a;
|
||||
if (y === y0 && upCold && a > 0.5) { hot[c - CW] = 6; hotLvl[c - CW] = 2; }
|
||||
}
|
||||
}
|
||||
rel = y < roofY[x] ? 0.02 : 0.002;
|
||||
} else rel = RELAX[m];
|
||||
t += (amb - t) * rel * sc;
|
||||
temp[i] = t;
|
||||
if (m !== EMPTY) { react(i, x, y, m); m = mat[i]; t = temp[i]; }
|
||||
const dv = t > amb ? t - amb : amb - t;
|
||||
if (dv > maxDev) maxDev = dv;
|
||||
if (flags[i] & F_BURN) burning = true;
|
||||
}
|
||||
}
|
||||
if (burning || maxDev > 1.5) { hot[c] = 6; hotLvl[c] = (burning || maxDev > 60) ? 2 : 1; }
|
||||
else hot[c]--;
|
||||
}
|
||||
Reference in New Issue
Block a user