I was just wondering why are are new generation microprocessors faster at the same clock speed as the old ones. For instance a 2.66Ghz dual core i5 is faster than the a device with clock speed of 2.66Ghz but core 2 dual.
If executing each instruction took a single clock-cycle, then your confusion would have been understandable, as a higher clock frequency would imply shorter cycle time, hence, more instructions per unit time.
However, the reality is quite different. Modern CPUs are usually pipelined, meaning that a single instruction takes multiple number or core-clocks, and that multiple instructions are executed simultaneously at the same time (each occupies different parts of the CPU pipeline). Complex instructions, such as calling a function or "jumping" to a different part of the code interfere with this pipeline and cause the CPU to temporarily halt its execution until the offensive instruction completes (known as a pipeline stall).
The picture is even more complex. Recent processors have multiple pipelines running on the same "core" (say, one clock advances pipeline 1 while the next clock advances pipeline 2). Of course, sometimes the program running on one pipeline affects (stalls) the progress of the other pipeline. This is "multithreading". Other approaches to make the CPU perform better are superscalar processing and other paralleling approaches.
As you can figure out, the number of instruction a CPU performs at any time unit is very complex to compute or even estimate, and is affected by the clock frequency, but also by the architecture of the CPU as well as by the program itself (e.g., how many "jumps" instructions it contains, or how well it parallelizes). All of these together determine the "speed" of the CPU, which is measured in the (average) number of instructions it can perform in a second, known as IPS. As said, the clock frequency is only one factor to the IPS, but in modern CPUs the specific architecture (rather than small differences in their clock frequency) dominates the IPS.
Modern x86/x64 CPUs are incredibly complicated. There can be dozens of instructions in various stages of execution flying around a CPU core at a given time. The cycle boundaries are just times when the various functional units synchronize with each other and work out what each one will be doing next.
A CPU can be made faster at the same clock rate by increasing the number of regions that can operate in parallel, increasing the amount they do per cycle, or increasing the fraction of time that they're actually in use. There can be tension between these approaches – e.g., increasing the number of execution units makes the chip larger, which increases travel-time delays, and you pay that penalty even if the code you're running doesn't have enough parallelism to use the extra units.
The gory details of how recent Intel processors differ from those of a decade ago can probably all be found in Agner Fog's optimization manuals, specifically the microarchitecture manual and instruction tables. They aren't really organized in a way to make comparing specific generations easy, but looking at the instruction tables for Wolfdale (45nm Core 2) and Ice/Tiger Lake, I see that many simple instructions have a throughput of 0.33 (i.e., three per cycle) on Wolfdale and 0.25 (four per cycle) on Ice/Tiger Lake, probably due to there being an additional execution unit that can handle them, and 128-by-64-bit integer divisions have a throughput of one per 10 cycles on Ice/Tiger Lake and one per 18-88 cycles on Wolfdale.
The microarchitecture manual says of Ice/Tiger Lake:
The pipeline is very similar to previous designs, but the number of execution units has been increased to improve the throughput from four to five instructions per clock cycle. The number of output ports is doubled so that the processor can do two memory reads and two memory writes per clock cycle under favorable circumstances. The size of the µop cache has been increased by 50%. [Wolfdale has no µop cache at all, though it has a small loop buffer which is a similar idea.] The resources for out-of-order execution have been increased further. The reorder buffer has 352 entries. [Wolfdale: 96] The reservation station has 160 entries. [Wolfdale: 32]
Ice/Tiger Lake also has 256-bit and 512-bit wide SIMD instructions, while Wolfdale only has 128-bit. This only benefits code that uses the new instructions, but a lot of software tests the CPU type at run time and uses new instructions when available, so a particular executable file may run faster on newer processors for this reason.
This is far from a complete list of changes and I encourage you to read Fog's manuals if you find this sort of thing interesting.
There are many techniques that can be applied.
At a higher level you have 2 main options:
- ILP: Instruction Level Parallelism
- TLP: Thread Level Parallelism
So increase parallelism in a single instruction stream or increase parallelism due to having multiple instruction streams.
Multicore (SMP) and hyperthreading (SMT) help to increase parallelism in multiple instruction streams.
Increasing parallelism in a single instruction stream can be done using:
- SIMD instructions
What you see with the Apple M1 is that it deals very well with super scalar execution. So it has a huge out of order execution window so it can keep its execution units busy and it has many execution units. So instead of betting on higher frequencies, it bets on improved superscalar execution.
There are also other techniques that can be applied to speed up processors like increasing the size of the caches, branch prediction, prefetching, NUMA, etc.