Take the 2-minute tour ×
Computer Science Stack Exchange is a question and answer site for students, researchers and practitioners of computer science. It's 100% free, no registration required.

I've always wondered why processors stopped at 32 registers. It's by far the fastest piece of the machine, why not just make bigger processors with more registers? Wouldn't that mean less going to the RAM?

share|improve this question
2  
I guess beyond a certain point all your local variables fit into the registers. The actual data you are working with is probably too large anyway –  Niklas B. Mar 13 at 15:28
10  
Diminishing returns. Clearly, registers are "more expensive" (in various senses) than RAM or we'd just have 8GB of registers. –  David Richerby Mar 13 at 16:22
4  
One of the reason its so fast is because there arent many of them. –  stackErr Mar 13 at 21:55
4  
There is a difference between how many registers the cpu has in total, and how many you can use at once. –  Thorbjørn Ravn Andersen Mar 14 at 14:48

4 Answers 4

up vote 52 down vote accepted

First, not all processor architectures stopped at 32 registers. Almost all the RISC architectures that have 32 registers exposed in the instruction set actually have 32 integer registers and 32 more floating point registers (so 64). (Floating point "add" uses different registers than integer "add".) The SPARC architecture has register windows. On the SPARC you can only access 32 integer registers at a time, but the registers act like a stack and you can push and pop new registers 16 at a time. The Itanium architecture from HP/Intel had 128 integer and 128 floating point registers exposed in the instruction set. Modern GPUs from NVidia, AMD, Intel, ARM and Imagination Technologies, all expose massive numbers of registers in their register files. (I know this to be true of the NVidia and Intel architectures, I am not very familiar with the AMD, ARM and Imagination instruction sets, but I think the register files are large there too.)

Second, most modern microprocessors implement register renaming to eliminate unnecessary serialization caused by needing to reuse resources, so the underlying physical register files can be larger (96, 128 or 192 registers on some machines.) This (and dynamic scheduling) eliminates some of the need for the compiler to generate so many unique register names, while still providing a larger register file to the scheduler.

There are two reasons why it might be difficult to further increase the number of registers exposed in the instruction set. First, you need to be able to specify the register identifiers in each instruction. 32 registers requires a 5 bit register specifier, so 3-address instructions (common on RISC architectures) spend 15 of the 32 instruction bits just to specify the registers. If you increased that to 6 or 7 bits, then you would have less space to specify opcodes and constants. GPUs and Itanium have much larger instructions. Larger instructions comes at a cost: you need to use more instruction memory, so your instruction cache behavior is less ideal.

The second reason is access time. The larger you make a memory the slower it is to access data from it. (Just in terms of basic physics: the data is stored in 2-dimensional space, so if you are storing $n$ bits, the average distance to a specific bit is $O(\sqrt{n})$.) A register file is just a small multi-ported memory, and one of the constraints on making it larger is that eventually you would need to start clocking your machine slower to accommodate the larger register file. Usually in terms of total performance this is a lose.

share|improve this answer
1  
+1 Great answer! –  stackErr Mar 13 at 21:53
1  
I would have mentioned SPARC64 VIIIfx's 256 FPRs and 32 extra non-window GPRs, accomplished by adding a Set XAR instruction which provides 13 bits each for the next one or two instructions. It was targeted at HPC, so the register count is more understandable. I would also have been tempted to expound on some of the trade-offs and techniques associated with more registers; but you showed the wisdom to avoid a more exhausting (and even then not exhaustive) answer. –  Paul A. Clayton Mar 14 at 0:06
2  
Adding a bit on the diminishing benefit of more registers for "general purpose" code might be worthwhile, though finding meaningful measurements is not easy. I think Mitch Alsup mentioned on comp.arch that extending x86 to 32 registers rather than 16 would have gained about 3% in performance compared to (ISTR) 10-15% for the 8 to 16 register extension that was chosen. Even for a load-store ISA, going to 64 probably provides little benefit (at least for current GP code). (BTW, GPUs often share registers across threads: e.g., one thread with 250 leaving on 16 total private for other threads.) –  Paul A. Clayton Mar 14 at 0:23
    
Interesting to see that environment management (hence alpha-conversion), often associated with high-level languages, is actually used down at the register level. –  babou Mar 14 at 9:16
    
@PaulA.Clayton I always thought that IA-64 is the architecture that has the largest number of ISA registers –  Lưu Vĩnh Phúc Mar 14 at 14:48

Just two more reasons for limiting the number of registers:

  • Little gain to be expected: CPU such as current Intel/AMD x64 models have 32kByte and more of L1-D cache, and access to the L1 cache usually takes only one clock cycle (compared to about a hundred clock cycles for a complete single RAM access). So there is little to be gained from having more data in registers compared to having data in the L1 cache
  • Additional computational costs: Having more registers creates an overhead that may actually make a computer slower:
    • In multitasking-environments, a task switch usually has to save the contents of all registers of the process that is left to memory, and has to load those of the process to be entered. The more registers you have, the longer this takes.
    • Similarly, in architectures without register windows, cascaded function calls use the same set of registers. So a function A calling a function B uses the same set of registers as B itself. Therefore, B has to save the contents of all registers it uses (which still hold A's values) and has to write them back before returning (in some calling conventions it is the job of A to save its register contents before calling B, but the overhead is similar). The more registers you have, the longer does this saving take, and thus the more expensive a function call becomes.
share|improve this answer
    
How does it work for the L1 cache so that we do not have the same problem as for the registers? –  babou Mar 14 at 9:07
1  
On high performance processors L1 Dcache latency is more typically 3 or 4 cycles (including address generation), e.g., Intel's Haswell has 4 cycle latency (not having a data dependence register latency is also easier to hide in the pipeline). Dcache also tends to support fewer accesses per cycle (e.g., 2 read, 1 write for Haswell) than a register file (e.g., 4 read, 6 write for Alpha 21264 which replicated the file, 2 files with 4 reads is faster than 1 with 8). –  Paul A. Clayton Mar 14 at 12:15
    
@PaulA.Clayton: If the L1 cache has a 3-4 cycle latency, that would suggest that there might be some benefit to having e.g. a few sets of 64 words of single-cycle memory with its own 64-word address space, and dedicated "load/store direct" instructions, especially if there were a way to push all the non-zero values followed by a word saying which words were non-zero, and then a way to pop them back (zeroing any registers not popped). Many methods have between 16 and 60 words of local variables, so cutting access time for those from 3-4 cycles to one would seem helpful. –  supercat Mar 14 at 22:35
    
@supercat Various stack (and global/TLS [e.g., Knapsack]) cache ideas have been presented in academic papers as well as mechanisms like the signature buffer (PDF) Actual use, not so much (it seems). This is getting chatty (so should probably end or go elsewhere). –  Paul A. Clayton Mar 15 at 2:42

Who tells you that processor always have 32 registers? x86 has 8, ARM 32-bit and x86_64 have 16, IA-64 has 128, and many more other numbers. You can have a look here. Even MIPS, PPC or any architectures that have 32 general purpose registers in the instruction set, the number is much larger than 32 since there are always still flag registers (if any), control registers... not including renamed registers and hardware registers

Everything has its price. The larger the number of registers, the more work you have when doing task switching, the more space you need in the instruction encoding. If you have less register, you don't have to store and restore much when calling and returning from functions or switching tasks with the trade off of lacking of registers in some compute-extensive code

Moreover, the larger the register file, the more expensive and complex it will be. SRAM is the fastest and most expensive RAM so it is only used in CPU cache. But it's still much cheaper and takes less area than a register file with the same capacity.

share|improve this answer

I am not an electrical engineer, but I think another possibility for the reason to limit the number of registers, is routing. There are a limited number of arithmetic units, and they must be able to take input from every register, and output to every register. This is especially true when you have pipelined programs that can execute many instructions per cycle.

A simple version of this would have $\mathcal O(n^2)$ complexity, making increasing the number of registers unscalable, or otherwise requiring a redesign of the routing to something a lot more complicated to route everything with a better complexity.

I got the idea for this answer from watching some of Ivan Godard's talks on the Mill CPU. Part of the innovation of the Mill CPU is that you cannot output to arbitrary registers - the outputs are all pushed onto a register stack or "belt", which thus reduces routing problems, because you always know where the output will go. Note they still have the routing problem for getting the input registers to the arithmetic units.

See The Mill CPU Architecture - the Belt (2 of 9) for the problem statement, and Mill's solution.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.