4 ms·
Yep, what really happens under the hood is dynamic register allocation at runtime. I wonder how important is static register allocation by the compiler in that
by bluetomcat 6y ago
Yep, what really happens under the hood is dynamic register allocation at runtime. I wonder how important is static register allocation by the compiler in that scenario. In theory, even if the compiler uses the same register over and over in sequential instructions, the renamer should be smart enough to detect the false data dependencies and allocate registers from individual instructions to different locations in the register file.
Are there any x86 profiling tools which give any metrics about the real utilisation of the register file?
- recraft 6y agoI don't know of any profiling tools, but I've always relied on llvm-mca[0] -register-file-stats to show me what the expected register file usage is on an ISA [0] https://llvm.org/docs/CommandGuide/llvm-mca.html https://llvm.org/docs/CommandGuide/llvm-mca.html
- Tuna-Fish 6y agoNot just in theory. The way modern register renaming works is that every single write to a register name always allocates a new physical register. It's not even possible for there to be false dependencies because of reusing the same name over and over.
- gpderetta 6y agoThe number of architectural registers are still relevant for register allocation because of course overlapping and independent code sequences cannot share the same architectural register name. This is not very important for integer loads, but still relevant for FP where optimal scheduling requires having multiple computations in flight at the same time. In some cases 16 FP registers are not enough and Intel had to add 16 more FP registers with AVX512.
- nx7487 6y agoOh: to clarify, you mean that the compiler could just use stack slots for everything, but some instructions are only allowed to operate on architectural registers, right? If you have to execute a lot of those instructions, the number of architectural registers can be the bottleneck in performance?
- easde 6y agoYes, consider vector floating point fused multiply-add (FMA). On a typical AVX implementation like Skylake, this instruction has a latency of 4 cycles and a throughput of 2 instructions per cycle. To avoid stalls, you'd need 4 * 2 = 8 instructions to run independently, and 8 architectural registers to simply store the results. You could store the results onto the stack and reuse the same architectural registers, but usually you want to use the values immediately in the next loop iteration (eg. matrix multiply) so this would be expensive. You probably want a few more architectural registers (at the very least 2, up to 16) to hold the inputs as well.
- gpderetta 6y agoexactly this. Thanks for the practical example. The reason it is less relevant for integer computations is that integer ops have normally lower latency and tend to have shorter loop carried dependency chains.