13

Some early RISC CPUs had branch delay slots, the theory being that this would make the CPU both cheaper and faster; you could omit some interlock circuitry, and at the same time, in some cases, execute another instruction in what would otherwise have been a wasted cycle. According to https://en.wikipedia.org/wiki/Delay_slot

Branch delay slots are found mainly in DSP architectures and older RISC architectures. MIPS, PA-RISC, ETRAX CRIS, SuperH, and SPARC are RISC architectures that each have a single branch delay slot; PowerPC, ARM, Alpha, and RISC-V do not have any. DSP architectures that each have a single branch delay slot include the VS DSP, μPD77230 and TMS320C3x. The SHARC DSP and MIPS-X use a double branch delay slot; such a processor will execute a pair of instructions following a branch instruction before the branch takes effect. The TMS320C4x uses a triple branch delay slot.

There is nowadays a consensus that it is best to omit such things from an architecture, on the grounds that while they may be helpful in early implementations, later implementations will prefer a larger number, and later still will have branch predictors which means there is no fixed number of delay slots, so it just becomes baggage.

At what point did pipelines become deep enough that, if you were going to design the architecture with delay slots at that time, the number of them to include would've been greater than one? For example, which MIPS CPU first found itself in the position of 'well, if we were going to have delay slots at all, the correct number would've been 2, so the architecturally specified 1 delay slot doesn't actually mean we can omit those interlocks'?

2 Answers 2

17

The 1 cycle branch delay slot of early RISC only really works with slow 5 levels pipeline. Branch decision must include instruction decode, branch calculation, then updating cache fetch address in the same cycle to allow 1 cycle branches.

It works for relative branches and subroutine calls with simplified decoding, it doesn't quite work with conditional branches (flags may be updated, or the branch instruction need to reach the execute stage to be decided).

With faster frequencies, processors have had to decouple instruction fetch (and branch prediction, target address caches, ...) from execution. At that point, branch delay slots had become a burden. Particularly with superscalar CPUs.

Faster frequency have resulted that instruction fetch latency becomes widely variable between cache hits and cache misses (nowadays it is tens to hundred cycles to reach L2 or L3 caches or DRAM). A decoupled pipeline is able to fetch instructions in advance of execution, to hide a bit memory latency, but the pre-fetch engine need to predict the instruction flow. A branch delay slot offers nothing but more complexity.

For example, with MIPS, the R4000 had a 8 levels pipeline and 3 cycles branch delay, already the 1 cycle delay slot wasn't quite sufficient. The delay saved a cycle when some useful instruction could be fit in the delay slot, which is not always the case. Only branch prediction can effectively reduce, on average, actual branch delay, more efficiently than any slot.

2

The PPUs in the CDC 6600 (a Seymour Cray design circa 1964 to 1969) were barrel processors and thus had a branch delay in cycles equal to the number of PPUs (8 or 10 IIRC). The delay slot execution cycles were taken up by the other PPUs.

3
  • 1
    IDNKT about CDC 6600 being a barrel processor. But each processor had a separate instruction stream where its instructions were sequential in memory, right? Like multi-core now? Or was it that you would assemble instructions interleaved??? (In which case it would be like the delay slots the question is asking about.) Are you talking about the peripheral CPUs, not the main CPU (with the floating point ALU and stuff)?
    – davidbak
    Nov 24, 2022 at 19:46
  • 2
    The 6600 CP was not a 'barrel processor'; the 10 PPs were, based on one set of computational hardware with 10 distinct register sets. Nevertheless, I would not characterize PP operation as having delay slots. Where there are delay slots, the process executes an instruction in the delay slot while the previous instruction is "in flight". As far as I know, the PP had no such capability: once a PP branch instruction was issued, that PP was stalled until the branch completed. This is not different to a 'conventional' implementation where the processor speed happens to be slower than memory. Nov 24, 2022 at 20:50
  • 2
    @davidbak - the PPs were not like multicore, but more like hyperthreading: one execution engine and 10 sets of processor state. The difference is that (as far as I know) hyperthread scheduling is dynamic, but PP slot/barrel operation was just fixed time-slicing. Nov 24, 2022 at 21:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .