Remove two recalcNodeList calls that have been no-ops - #23
Open
Roxxik wants to merge 1 commit into
Open
Conversation
setNode has settled the netlist itself since aed0d9a moved recalcNodeList into it. The calls that follow setNode in step and initAndResetChip predate that commit and have been no-ops ever since. recalcNodeList leaves both worklists empty: its loop exits when lists_switch has just swapped an empty listout into listin, and listout_clear then zeroes listout and its bitmap. A second call switches two empty lists, sees an empty listin, and breaks on the first iteration without visiting a node. All it costs is a 216-byte memset per half-cycle, so no simulation result changes and the benchmark does not move.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
setNodeends with its ownrecalcNodeList. The calls that follow it instepand
initAndResetChipdo nothing, and have done nothing sinceaed0d9amovedrecalcNodeListintosetNode. Both call sites predate that commit and weresimply not removed with it.
The code as it stands says the opposite: that
setNodehands back an unsettlednetlist and the caller is responsible for settling it. That has not been true since that commit,
and
14983afalready relies on it not being true: it batcheswriteNodesprecisely becausesetNoderecalculates on every call.Why it is a no-op
recalcNodeListleaves both worklists empty, not just the output list:!listin_count(state)test, which is reached straightafter
lists_switchhas swapped an emptylistoutintolistin. Solistinis empty on return.
listout_clearthen zeroeslistout.countand memsetslistout_bitmap.A second call switches two empty lists, sees an empty
listin, and breaks oniteration zero without visiting a node. The one thing it does is a
bitmap_clearover an already-zero bitmap: 216 bytes memset per half-cycle.
This also holds on the loop-limiter path. If the 50-iteration guard fires,
listincan be left non-empty, but the next call'slists_switchswaps thejust-cleared
listoutin before the count is tested, so it still breaksimmediately.
Verification
cbmbasic --benchmarkis the only workload in this repo, and it is a poor testof a solver change: one path through the netlist, no undocumented opcode, no
interrupt, barely any decimal mode. So the checking below was done with two
harnesses that are not in this repo, Klaus Dormann's 6502 functional test and
Tom Harte's SingleStepTests, plus a digest that folds all 1725 node values into
a hash at a fixed cycle interval, so two builds can be compared node by node
instead of at the registers.
First, that the second call has no work to do. An instrumented build checks
listin.count,listout.countand every word oflistout_bitmapimmediatelybefore the second call in
step:stepcallscbmbasictoREADY.The
recalcNodeListloop-limiter warning did not fire once in either run, so thepathological path above was never taken and is argued rather than exercised.
Then, that removing it changes nothing. Node digests are identical, so the
two builds agree on all 1725 nodes at every sample point:
cbmbasic --benchmarkhalf-cyclescbmbasicfinalchipStatusAB:FFCF D:FF PC:FFCF A:00 X:00 Y:0A SP:F5 P:16 IR:20The functional test by Klaus Dormann was run to 2M cycles rather than to completion. It is a
hash comparison between two builds, not a pass/fail run, and the hashes
diverge at the first differing node whenever they are going to diverge at all.
Removing only the
stepcall gives the same hashes as removing both, so the twosites were checked separately as well as together.
Performance
There is none, and none is claimed. Three interleaved pairs of
cbmbasic --benchmark:Under 1%, inside run-to-run noise. A 216-byte memset is nothing next to the
~1725-node solve it sits beside. This is a clarity change: it removes a line that
misstates
setNode's contract.Machine
AMD Ryzen 5 7640U (Zen 4), 6C/12T. Kernel 7.1.4-arch1-1, gcc 16.1.1,
-O3.Benchmark runs interleaved, both sides built up front and never rebuilt between
runs. The figures above are three raw runs per side, not medians. The point of
the row is that the two ranges overlap, not what either value is.
I used an LLM to help me out in this work, but I manually reviewed all changes made.