Widen the memory controller's path to sixteen bits
The controller now reaches bank memory two bytes at a time, so a transfer whose source, destination and length are all even moves two bytes a cycle between banks and one within a bank - twice what each was. A 256 byte block between banks falls from 257 cycles to 129. Alignment is required all three ways because a word is read at an even address and written at an even address; an odd anything would mean shifting bytes across word boundaries to line them up, which is a different design. A misaligned transfer falls back to the byte a cycle it cost before, so nothing already written got slower. THE CPU DOES NOT CHANGE. It still sees eight bits, a Data Pointer still addresses a byte, and no instruction means anything different. This is a peripheral getting faster, which is why it is worth doing now rather than after more is built on top of it. The rule is deliberately visible rather than smoothed over: aligning a buffer costs nothing and halves what moving it costs, and a cost a program cannot see is a cost it cannot avoid. Tests/cycles.sh is new, and is the test the Test Manual has always said this kind of change would need - run.sh strips the cycle count from every recorded result, so nothing else in the suite can see any of this. It pins the RATE rather than a total: each case runs twice from programs whose instructions are identical but for the byte written to the Command port, once asking for the transfer and once for GuardOff, which costs nothing beyond the port write. The difference is the transfer and nothing else. Verified by disabling the widening, which failed exactly the three aligned cases and left the five misaligned ones passing. The Programming Manual gains a section saying what a transfer costs, which it never said at all - it only promised a transfer does not wait, which is a different claim and could be read as promising it is free. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
c3c2451afe
commit
4c3eac8d9c
@@ -604,6 +604,26 @@ Everything a transfer would touch is checked before any of it moves. A transfer
|
||||
|
||||
Filling is worth reaching for. Clearing a page with one Fill instead of a store and a loop takes about a tenth off the running time of the segmented sieve, which spends most of its life zeroing its window.
|
||||
|
||||
### What A Transfer Costs:
|
||||
|
||||
A transfer does not wait on anything, but it is not free. The controller is charged for every byte it moves, and the program that asked stalls until it is done, so these are cycles out of that program's budget.
|
||||
|
||||
Two things set the rate. **Banks are separate memories**, so a move between two of them can fetch the next word while the last one is stored, and a move within a single bank cannot and costs twice as much. And **the controller's path to memory is sixteen bits wide**, so it moves two bytes at a time when the addresses allow.
|
||||
|
||||
They allow it when the source, the destination and the length are **all even**. A word is read at an even address and written at an even address; an odd anything would mean shifting bytes across word boundaries to line them up, which is a different machine. A misaligned transfer falls back to a byte a cycle, which is what this cost before the path was widened.
|
||||
|
||||
| Moving 256 bytes | Aligned | Not aligned |
|
||||
| --- | --- | --- |
|
||||
| Between two banks | 129 | 257 |
|
||||
| Within one bank | 257 | 513 |
|
||||
| Fill | 129 | 257 |
|
||||
|
||||
The odd cycle in each is the pipeline filling. A fill has nothing to read, so it goes at the between-banks rate whatever bank it writes, and only its destination and length decide whether it can be paired - the byte it writes lives in SourceLow and is a value rather than an address.
|
||||
|
||||
**The rule is visible so that a program can act on it.** Aligning a buffer costs nothing and halves what moving it costs, and a cost a program cannot see is a cost it cannot avoid.
|
||||
|
||||
None of this changes the CPU. It still sees eight bits, a Data Pointer still addresses a byte, and no instruction means anything different than it did. What got wider is the controller's own path to the memories it moves between.
|
||||
|
||||
### Banks:
|
||||
|
||||
Memory the controller can reach is divided into banks of up to 64K each, numbered 0 to 255. Program and Data are banks like any other; being 0 and 1 is the only thing special about them.
|
||||
|
||||
Reference in New Issue
Block a user