3 ms·
I thought between modern compilers and supporting 4 op/cycle with out-of-order execution, a new Kaby Lake cpu would get more than 1 cycle overall. Or are the br
by gvb 10y ago
I thought between modern compilers and supporting 4 op/cycle with out-of-order execution, a new Kaby Lake cpu would get more than 1 cycle overall. Or are the branch delays just killing the performance?
The problem at the level of how many operations per cycle is data dependencies. A lot of code is assignments to variables and subsequent use of those variables in calculations, etc. Simplistic example:
a = 1;
b = 2;
c = a + b;
The assignment to variable "c" stalls until "a" and "b" assignments are completed. Obviously, in real life the assignments of "a" and "b" would generally be other complicated assignments that are dependent on other variables, functions, calculations, etc.
The x86 is additionally hampered by its relative lack of registers. This is hidden to some extent by using register renaming so that the CPU actually has multiple instances of register e.g. AX and tracks the dependencies.
Ref:
https://en.wikipedia.org/wiki/Register_allocation https://en.wikipedia.org/wiki/Register_allocation
https://en.wikipedia.org/wiki/Register_renaming https://en.wikipedia.org/wiki/Register_renaming
- ant6n 10y agoSkylake has up to 224 instructions in flight [1], apparently on multiple branches. This compares to your 3 instruction example. I think it's a valid question whether this doesn't imply we get more than 1 instruction/cycle, even for code that isn't hand-optimized (i.e. just usual code optimized by the compiler), assuming that the work load isn't data-memory bound. [1] http://www.anandtech.com/show/9582/intel-skylake-mobile-desktop-launch-architecture-analysis/5 http://www.anandtech.com/show/9582/intel-skylake-mobile-desk...
- gvb 10y agoYou will get the number of instructions in parallel that is the minimum of (a) the number of instructions that can be handled by the hardware simultaneously and (b) the number of instructions that don't have inter-dependencies. My example was not a 3 instruction example. It was a minimum example of data dependencies. In the example, until the CPU can resolve what the value of the variable (register) "a" is, it cannot do the calculation for the variable "c". Most programs have a high level of data inter-dependencies. Conditional branches are major class of data inter-dependency - the CPU cannot execute code beyond the branch[1] until it knows which branch it will take. There is a class of programs that are "embarrassingly parallel" that having more execution units will speed them up, ideally linearly (graphics GPUs are a classic example). "Garden variety" programs end up under utilizing execution units because the execution unit assigned to calculate "c" (from my example) will be stalled waiting for execution units assigned to calculate "a" and "b" to complete their calculations. This is related to the long unrealized, and still unrealized, promise of VLIW architectures. https://en.wikipedia.org/wiki/Very_long_instruction_word https://en.wikipedia.org/wiki/Very_long_instruction_word [1] A small-ish lie: many processors nowadays do "speculative execution" where they guess which branch will be taken and execute ahead. If they guess right, they win. If they guess wrong, they throw away the work they did and restart the execution on the other branch.
- psykotic 10y agoEven with an embarrassingly parallel problem, you need to have enough compute work per memory access to achieve anything like full utilization. Suppose you're doing a pairwise multiplication of two huge arrays. That's as embarrassingly parallel as it gets. Even better, it's a perfect fit for SIMD. But as the article shows, you'll get nowhere near the theoretical throughput of 4 instructions/cycle since there's not enough main memory bandwidth. You could add infinitely large issue and retire queues and infinitely many execution units to the out-of-order core. You'd still be bottlenecked by memory bandwidth.