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
@@ -135,10 +135,18 @@ assembling a program.
|
||||
|
||||
**The memory controller is charged for what it moves**, on the same terms. Banks are
|
||||
separate memories, and that is what sets the rate: a move between two of them can overlap
|
||||
its read and its write, so it settles at a byte a cycle, while a move within one bank cannot
|
||||
and costs two. A fill has nothing to read and costs one. So a 256 byte block is 257 cycles
|
||||
between banks and 513 within one, against the ten it used to cost - which was the five port
|
||||
writes that set it up and nothing for the quarter of a kilobyte that moved.
|
||||
its read and its write, while a move within one bank cannot and costs twice as much. A fill
|
||||
has nothing to read and goes at the between-banks rate. Against the ten cycles a transfer
|
||||
used to cost - the five port writes that set it up, and nothing at all for the quarter of a
|
||||
kilobyte that moved.
|
||||
|
||||
**And the controller's path to memory is sixteen bits wide.** A transfer whose source,
|
||||
destination and length are all even moves two bytes a cycle between banks and one within a
|
||||
bank; anything odd falls back to a byte a cycle, because lining bytes up across word
|
||||
boundaries is a second design and this is not it. So a 256 byte block is 129 cycles between
|
||||
banks and 257 within one when it is aligned, and 257 and 513 when it is not. The CPU still
|
||||
sees eight bits and no instruction means anything different: this is a peripheral being
|
||||
faster, not a new machine.
|
||||
|
||||
The transfer stalls the program that asked for it. Whether hardware would let the two run at
|
||||
once is left open, the same way pipelining is: the memories are separate, so it plausibly
|
||||
|
||||
Reference in New Issue
Block a user