1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 08:55:38 +00:00

sha256/computing: track byte offsets directly to skip per-iter shift

The phased compression driver was computing the schedule/round
*index* per iteration and then shifting it left by 2 to get the
byte offset (`schedule_one(i << 2)`, `round_one(r << 2)`). The
shift compiles to two ASLs per iteration — cheap, but pure dead
work since the byte offset is just the previous one + 4.

Track the byte offset as the loop counter and bump it by 4 each
iteration. The schedule and round APIs already wanted byte
offsets, so the call sites also get a touch shorter (no more
intermediate `var i: u8 = first_idx + step`).

Strict cycle savings are tiny — a handful per iteration — so
this is more about not leaving obviously redundant work in the
inner loop than a meaningful perf win. Hash output unchanged
(still AE9145DB…4E0D for "NES"); no other examples affected;
emulator harness 34/34.

https://claude.ai/code/session_01FRmSBruVWCufm3LsUVMs8v
This commit is contained in:
Claude 2026-04-16 17:17:10 +00:00
parent df71c2bf50
commit f2623cb62b
No known key found for this signature in database
2 changed files with 18 additions and 10 deletions

Binary file not shown.

View file

@ -32,24 +32,32 @@ state Computing {
on frame { on frame {
if cp_phase < SCHED_PHASES { if cp_phase < SCHED_PHASES {
// Each schedule phase handles BATCH_SIZE words. // Each schedule phase handles BATCH_SIZE words. The
// First word index for this phase: 16 + phase * 4. // schedule_one / round_one APIs both want a byte
var first_idx: u8 = 16 + (cp_phase << 2) // offset (= word_index * 4), so track that directly
// instead of recomputing `index << 2` per iteration:
// the byte offset is just incremented by 4 in lieu
// of the index by 1.
//
// First byte offset for this phase: (16 + phase*4)*4
// = 64 + phase * 16.
var w_byte: u8 = 64 + (cp_phase << 4)
var step: u8 = 0 var step: u8 = 0
while step < BATCH_SIZE { while step < BATCH_SIZE {
var i: u8 = first_idx + step schedule_one(w_byte)
schedule_one(i << 2) // byte offset into w[] w_byte += 4
step += 1 step += 1
} }
cp_phase += 1 cp_phase += 1
} else if cp_phase < FOLD_PHASE { } else if cp_phase < FOLD_PHASE {
// Round batch. First round for this phase: // Round batch. First byte offset for this phase:
// (phase - SCHED_PHASES) * 4. // (phase - SCHED_PHASES) * 4 * 4
var first_r: u8 = (cp_phase - SCHED_PHASES) << 2 // = (phase - SCHED_PHASES) << 4.
var kw_byte: u8 = (cp_phase - SCHED_PHASES) << 4
var step2: u8 = 0 var step2: u8 = 0
while step2 < BATCH_SIZE { while step2 < BATCH_SIZE {
var r: u8 = first_r + step2 round_one(kw_byte)
round_one(r << 2) // K/W share byte 4*i kw_byte += 4
step2 += 1 step2 += 1
} }
cp_phase += 1 cp_phase += 1