4 ms·
That is a perfectly reasonable approach to that answer indeed. Registers do hold state and saving restoring them is burden of program code (user, compiler, lib,
by ithkuil 6y ago
That is a perfectly reasonable approach to that answer indeed. Registers do hold state and saving restoring them is burden of program code (user, compiler, lib, os).
Contrast this with a hypothetical cpu that has only one register "base" and allows to address 32 words after the address at that base register. i.e. things like arithmetic instructions would have 5 bits to address operands which will be interpreters as base+8*n. To make things even more interesting this architecture's instruction pointer lives at base+0.
Such an architecture would have one register under your metric (as only one register needs to be saved/restored to context switch an entire "register file").
However, implementations (microarchitecture) could actually shadow that memory range into hardware registers, and page in/out the whole register bank upon writes of the base register (effectively performing a hardware assisted context switch; hello TSS).
However, since each instruction in this hypothetical ISA must have enough space in the encoding to address these operands, for all intents and purposes this architecture would have 32 registers.
Deciding instructions, addressing operands, dealing with consequences of code density (icache misses), ... are all way more frequent events than context switches.
Hence I do agree with TFA that operand encoding should be the default metric to count registers. And this also includes sub/overlapping registers, if they are independently addressed.
- jcranmer 6y agoWeird architectures definitely make the question a lot more difficult to answer. My gut reaction would be to say that your hypothetical ISA has 33 registers, and that the register file is memory-mapped to a specified region of virtual memory. That's partially because of the way that you're going to worry about how cache coherence will work out, but also because I suspect the mcontext_t or OS-equivalent interface will also define its structure layout as such. The broader point, though, is in deciding whether or not to include registers like CR0 and DR0. The principle I'm using here is that registers that are not expected to be saved/restored on task switches should be excluded. Registers that are per-process (i.e., page tables in general, or segment descriptors on x86) or per-CPU (most MSRs) are thus excluded by this criterion. FSBASE/GSBASE are extremely borderline--I wouldn't complain if they were or if they weren't excluded from a list of registers. These act as a mixture of user-visible registers (even if accessibly only via syscalls until very recently) and segment descriptor information. They're not in Linux's userspace-visible mcontext_t struct, but they are in the kernel's equivalent to mcontext_t.
- ithkuil 6y agoThe goal of the hypothetical ISA in my example was merely to tease apart two distinct aspects of the register file cardinality. Both aspects (state and encoding) exist in real world architectures but apparently it's easy to confuse them.
- bitwize 6y ago> Contrast this with a hypothetical cpu that has only one register "base" and allows to address 32 words after the address at that base register. This, er, wasn't really hypothetical. The TMS9900, the CPU used in the TI-99/4A, had three hardware registers: a program counter, a status word, and what was called a Workspace Pointer (WP). General purpose "registers" lived in RAM, and were referenced by an offset off the value in the WP. Subroutine calls were initiated by saving the PC and changing the WP to a fresh new register context before branching.