You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Read the IPC before you start. Perry retires instructions more efficiently than Node here
(4.28 vs 3.16) and still loses 6.29x. Nothing is stalling; the machine is executing the work
well. There are simply 8.5x too many instructions. Do not go looking for a cache or memory
problem — this is a "delete work" task, not a "speed up work" task.
Workload: gc-handoff/apps/typed_array.ts — bcryptjs's Blowfish _encipher shape, S/P
Int32Arrays reached through untyped parameters, ~4.27 M calls, indexed with >>>/| and
accumulated with +/^. Prints only checksum:-821955270, which must not change.
What is already known — do not re-derive any of this
The S-box element loads are already native. Optimized AArch64 shows ldr ..., [base, index, uxtw #2] — no NaN-box round trip, no per-element registry lookup.
An earlier agent assumed otherwise, built a "focused exact-index optimization", got −24.6%
instructions almost entirely on the typed path, and correctly reverted it because it made
the untyped/typed ratio worse.
perf(codegen): preserve numeric envelope proofs #8491 already took −44.1% wall / −34.7% instructions / −52.6% RSS out of this workload
by making a numeric type proof survive reassignment (number_by_construction). What remains
is a different part of the envelope, or something else entirely.
Method
Profile before hypothesising. Perry strips its output binaries, so compile with PERRY_KEEP_SYMBOLS=1 PERRY_DEBUG_SYMBOLS=1 or sample attributes everything to ???.
Aggregate over many runs. #8491 removed what used to be the dominant leaves
(js_number_coerce, js_dynamic_bitxor, js_dynamic_string_or_number_add, lookup_registered_typed_array_kind), so the current profile is genuinely unknown.
An 8.5x instruction ratio against a mature JIT on a tight integer loop usually means something
structural is still on the per-iteration path — a guard, a bounds check, a rooting store, a
call that should have been inlined. Find which before changing anything.
Acceptance
Meaningful instruction reduction. Instructions retired is the primary signal.
checksum:-821955270 unchanged; all 20 corpus programs byte-exact.
Time the whole 20-row corpus before and after; report every row moving more than 1%.
Peak RSS is 0.06x Node here — enormous headroom, but the standing constraint is to minimize
RSS while keeping the best compute. Quantify and argue any RSS cost rather than spending it
quietly.
Opt target 1 —
typed_array: 6.29x Node, 8.52x instructionsThis is the single largest remaining gap in the corpus, roughly three times worse than
anything else Perry runs. Take this one first.
Measurement — quiet M1 mini, 5 shuffled interleaved repeats, verdict CLEAN, perry
fefdc367bRead the IPC before you start. Perry retires instructions more efficiently than Node here
(4.28 vs 3.16) and still loses 6.29x. Nothing is stalling; the machine is executing the work
well. There are simply 8.5x too many instructions. Do not go looking for a cache or memory
problem — this is a "delete work" task, not a "speed up work" task.
Workload:
gc-handoff/apps/typed_array.ts— bcryptjs's Blowfish_enciphershape,S/PInt32Arrays reached through untyped parameters, ~4.27 M calls, indexed with
>>>/|andaccumulated with
+/^. Prints onlychecksum:-821955270, which must not change.What is already known — do not re-derive any of this
ldr ..., [base, index, uxtw #2]— no NaN-box round trip, no per-element registry lookup.An earlier agent assumed otherwise, built a "focused exact-index optimization", got −24.6%
instructions almost entirely on the typed path, and correctly reverted it because it made
the untyped/typed ratio worse.
Both paths are slow together. Chasing the ratio chases a solved problem.
by making a numeric type proof survive reassignment (
number_by_construction). What remainsis a different part of the envelope, or something else entirely.
Method
Profile before hypothesising. Perry strips its output binaries, so compile with
PERRY_KEEP_SYMBOLS=1 PERRY_DEBUG_SYMBOLS=1orsampleattributes everything to???.Aggregate over many runs. #8491 removed what used to be the dominant leaves
(
js_number_coerce,js_dynamic_bitxor,js_dynamic_string_or_number_add,lookup_registered_typed_array_kind), so the current profile is genuinely unknown.An 8.5x instruction ratio against a mature JIT on a tight integer loop usually means something
structural is still on the per-iteration path — a guard, a bounds check, a rooting store, a
call that should have been inlined. Find which before changing anything.
Acceptance
1.0017 now and must not regress materially. An optimization that only helps the typed path
reopens Perf: untyped typed-array element access ~6x slower (per-access thread-local kind lookup) — bcryptjs cost-12 ~28s vs ~250ms #5525 and will be rejected.
checksum:-821955270unchanged; all 20 corpus programs byte-exact.RSS while keeping the best compute. Quantify and argue any RSS cost rather than spending it
quietly.