MIPS Architecture

The MIPS (Microprocessor without Interlocked Pipeline Stages) architecture is a well-known RISC (Reduced Instruction Set Computer) design that is widely used in both academic and industrial applications. This architecture is characterized by three fundamental principles: a streamlined instruction set, a load/store-based memory access model, and a pipeline execution mechanism. These features contribute to its efficiency, making MIPS an important subject of study in computer architecture.

RISC Architecture

MIPS follows the RISC philosophy, which emphasizes simplicity in instruction execution. Unlike Complex Instruction Set Computers (CISC), which incorporate complex multi-cycle instructions, RISC architectures rely on a small set of simple, fixed-length instructions that execute in a uniform number of cycles. This design choice reduces the complexity of the control logic and enhances execution speed.

By focusing on straightforward instructions that complete in a single cycle whenever possible, the MIPS architecture enables high performance and efficient instruction pipelining. Additionally, RISC architectures tend to have a larger number of general-purpose registers to minimize the frequency of memory accesses, further optimizing execution speed and energy consumption.

Load/Store Architecture

Another fundamental aspect of the MIPS architecture is its load/store memory access model. Unlike some architectures where arithmetic and logic operations can directly access memory, MIPS enforces a strict separation between computation and data movement. This means that the Arithmetic Logic Unit (ALU) operates only on registers, requiring explicit instructions to move data between memory and registers.

To facilitate data transfer, MIPS provides dedicated load and store instructions:

  • Load Instructions (e.g., LW - Load Word, LB - Load Byte): These instructions transfer data from memory into registers before it can be processed.
  • Store Instructions (e.g., SW - Store Word, SB - Store Byte): These instructions write data from registers back into memory.

This approach simplifies hardware design and improves the predictability of instruction execution. It also enhances the efficiency of instruction pipelining since memory access operations are isolated from computation, reducing potential bottlenecks.

Pipeline Architecture

To further optimize performance, MIPS employs a pipelining mechanism, a technique that allows multiple instructions to be executed simultaneously at different stages of completion. Instead of executing each instruction sequentially, MIPS divides the execution process into distinct phases, such as:

Steps

  1. Instruction Fetch (IF): The instruction is retrieved from memory.
  2. Instruction Decode (ID): The instruction is analyzed, and operands are identified.
  3. Execute (EX): The operation is performed using the ALU.
  4. Memory Access (MEM): If needed, memory is accessed for load or store operations.
  5. Write Back (WB): The result is stored in the appropriate register.

By allowing instructions at different stages to overlap, pipelining significantly improves throughput, as multiple instructions are in progress at any given time. However, this approach introduces challenges such as data hazards (when instructions depend on previous results), control hazards (when branches affect execution flow), and structural hazards (when hardware resources are over-utilized). To mitigate these issues, MIPS incorporates techniques such as forwarding, branch prediction, and pipeline stalls, ensuring efficient instruction execution.

Reduced Instruction Set on MIPS processors

The MIPS architecture is based on a reduced instruction set (RISC), meaning that the instruction set consists of a small number of simple instructions. One of the main advantages of RISC architectures is that they execute instructions faster than CISC architectures. This is because each instruction is simple and designed to execute in a single clock cycle. In contrast, CISC architectures rely on complex instructions that often take multiple clock cycles to complete.

There are three main types of instructions in the MIPS architecture:

  1. ALU instructions: These instructions perform arithmetic and logical operations on data stored in the CPU registers. For example:

    add rd, rs1, rs2        # $rd <- $rs1 + $rs2
    addi rd, rs1, 4         # $rd <- rs1 + 4

    The first instruction is a register-register operation, meaning both operands and the result reside in registers. The second is a register-immediate operation, which uses a constant value.

  2. Load/store instructions: These instructions move data between CPU registers and memory. Since MIPS follows a load/store architecture, data must first be loaded into a register before it can be processed. Similarly, results must be stored back into memory explicitly. For example:

     ld rd, offset (rs1)     # rd <- M[rs1 + offset] 
     sd rs2, offset (rs1)    # M[rs1 + offset] <- rs2

    The ld (load) instruction retrieves data from memory and places it into a register, while the sd (store) instruction writes data from a register into memory.

  3. Branch instructions: Branch instructions alter the flow of execution based on specific conditions. They are divided into conditional and unconditional branches:

    • Conditional Branch Instructions: These instructions modify the execution flow based on a comparison between two registers:
    beq rs1, rs2, L1        # go to L1 if (rs1 == rs2)
    bne rs1, rs2, L1        # go to L1 if (rs1 != rs2)
    • Unconditional Branch Instructions: These instructions jump to a specific address regardless of any condition:
    j   L1          # go to L1
    jr  ra          # go to add. contained in ra

Format of MIPS 32-bit Instructions

The MIPS architecture follows a fixed 32-bit instruction format, meaning that each instruction occupies exactly one word (4 bytes) in memory. This consistency simplifies instruction decoding and contributes to the efficiency of the processor’s pipeline execution. MIPS instructions are categorized into three primary formats: R-type (Register format), I-type (Immediate format), and J-type (Jump format). Each format serves a distinct role in instruction execution, enabling efficient computation, memory access, and program control flow.

R-Type Instructions (Register Format)

R-type instructions are used for arithmetic, logical, and shift operations that involve registers. These instructions operate directly on values stored in the CPU’s general-purpose registers, avoiding unnecessary memory accesses and ensuring high-speed execution. The format of an R-type instruction consists of six fields, as follows:

Each field has a specific purpose:

  • op (6 bits): Operation code (opcode), which specifies the category of the instruction. For R-type instructions, this field is always 000000 because the actual operation is determined by the funct field.
  • rs (5 bits): Source register, representing the first operand.
  • rt (5 bits): Target register, representing the second operand.
  • rd (5 bits): Destination register, where the result is stored.
  • shamt (5 bits): Shift amount, used for shift operations like sll (shift left logical) and srl (shift right logical). For other instructions, this field is set to 00000.
  • funct (6 bits): Function code, which specifies the exact operation within the R-type instruction class.

Example

For example, the addition instruction in MIPS assembly:

add $t0, $t1, $t2  # $t0 = $t1 + $t2

is encoded in binary as follows:

where 100000 in the funct field represents the add operation.

I-Type Instructions (Immediate Format)

I-type instructions are used for operations that involve immediate values (constants) or require memory access, such as load (lw), store (sw), and branch instructions (beq, bne). Unlike R-type instructions, which rely solely on register operands, I-type instructions include a 16-bit immediate field, making them suitable for memory addressing and arithmetic operations with constants.

The format of an I-type instruction is:

The meaning of each field is as follows:

  • op (6 bits): Opcode, which determines the instruction type.
  • rs (5 bits): Source register, providing an operand for arithmetic or memory operations.
  • rt (5 bits): Target register, either used for storing results (e.g., addi) or for addressing (lw, sw).
  • immediate/offset (16 bits): Immediate value used in computations (addi) or an offset used in memory access (lw, sw).

Example

For instance, the immediate addition instruction:

addi $t0, $t1, 5  # $t0 = $t1 + 5

is encoded as:

where 001000 represents the addi opcode, and 0000 0000 0000 0101 is the immediate value 5.

Similarly, a load word instruction:

lw $t0, 8($t1)  # Load from memory address ($t1 + 8) into $t0

uses the offset (8) to access memory relative to the base register $t1.

J-Type Instructions (Jump Format)

J-type instructions are responsible for unconditional jumps in program execution. Unlike branch instructions (which depend on conditions), jump instructions unconditionally transfer control to a new memory address. These instructions have a simpler format because they require only two fields:

where:

  • op (6 bits): Opcode, indicating the jump operation (j, jal).
  • address (26 bits): Target address to which control is transferred.

Since the program counter (PC) in MIPS increments by 4 bytes per instruction, the 26-bit address in a J-type instruction is multiplied by 4 to generate a full 28-bit jump address. The upper 4 bits of the new address are taken from the current PC.

Example

For example, the jump instruction:

j 10000  # Jump to address 10000 (decimal)

is encoded as:

where 000010 represents the j opcode, and the binary representation of 10000 (shifted right by 2 bits) fills the address field.

Phases of Execution of MIPS Instructions

In the MIPS architecture, each instruction is executed in a structured sequence of operations that take place across a maximum of 5 clock cycles. This pipeline-based execution model allows efficient instruction processing by overlapping operations from different instructions. The five fundamental phases of execution are as follows:

  1. Instruction Fetch (IF)
    During the instruction fetch phase, the Program Counter (PC), which holds the address of the next instruction to be executed, is sent to the Instruction Memory (IM). The processor retrieves the instruction stored at this address. Since each MIPS instruction is 4 bytes (32 bits) long, the PC is incremented by 4 to point to the next instruction in memory. This phase ensures a continuous flow of instructions into the pipeline.

  2. Instruction Decode and Register Read (ID)
    Once the instruction is fetched, it must be decoded to determine its type and extract the relevant fields. During this phase:

    • The opcode field is analyzed to determine the category of the instruction (arithmetic, memory access, or control).
    • If the instruction requires operands from registers, the corresponding register values are read from the Register File (RF).
    • If the instruction involves an immediate value or memory offset, it is sign-extended to 32 bits to match the ALU operand size. This step prepares all necessary data before execution, ensuring the correct operands are available for subsequent operations.
  3. Execution (EX)
    The execution phase varies based on the type of instruction being processed:

    • Register-Register ALU Instructions: The Arithmetic Logic Unit (ALU) performs the operation specified in the instruction (e.g., addition, subtraction, AND, OR) using the values read from the two source registers.
    • Register-Immediate ALU Instructions: The ALU processes the operation using one register operand and a sign-extended immediate value.
    • Memory Access Instructions: If the instruction is a load (lw) or store (sw), the ALU calculates the effective memory address by adding the base register value to the sign-extended offset.
    • Branch Instructions: If the instruction is a conditional branch (e.g., beq, bne), the ALU compares the values of the two registers. If the condition is met, the potential branch target address is computed by adding the sign-extended offset to the incremented PC.
  4. Memory Access (ME)
    The memory access phase is relevant only for load, store, and branch instructions:

    • Load (lw) Instructions: The computed memory address is used to read data from Data Memory (DM).
    • Store (sw) Instructions: The computed address is used to write data from the source register into Data Memory.
    • Conditional Branch Instructions: If the branch condition evaluates to true, the PC is updated to the branch target address computed in the execution phase. For instructions that do not involve memory operations (such as purely computational ALU instructions), this phase is skipped.
  5. Write-Back (WB)
    The final phase, write-back, updates the Register File (RF) with the results of the instruction:

    • For ALU instructions, the computed result is written to the destination register.
    • For load (lw) instructions, the data retrieved from memory is stored in the destination register. Store (sw) and branch instructions do not require this phase since they do not write to registers.

Basic Implementation of the MIPS Datapath

The MIPS processor consists of several key components that work together to execute instructions efficiently. These components are interconnected to form the MIPS datapath, which facilitates instruction execution.

  1. Instruction Memory (IM)
    The Instruction Memory (IM) stores the program’s instructions. The processor fetches instructions from this memory based on the current Program Counter (PC) value. Since MIPS instructions are 32-bit fixed-length, the PC is incremented by 4 after each instruction fetch to access the next sequential instruction.

  2. Register File (RF)
    The Register File (RF) contains 32 general-purpose registers, each 32 bits wide. These registers serve as the primary storage for instruction operands and computation results. The MIPS register file has:

    • 2 read ports, allowing two registers to be read simultaneously.
    • 1 write port, enabling the processor to update one register per clock cycle. This dual-read, single-write structure supports the efficient execution of instructions requiring multiple register operands.
  3. Arithmetic Logic Unit (ALU)
    The Arithmetic Logic Unit (ALU) performs computations on register operands. It supports arithmetic operations (e.g., addition, subtraction) and logical operations (e.g., AND, OR, XOR). The ALU is critical in:

    • Executing arithmetic instructions such as add, sub, and mul.
    • Calculating memory addresses for load (lw) and store (sw) instructions.
    • Performing comparisons for branch instructions like beq and bne.
  4. Data Memory (DM)
    The Data Memory (DM) is used to store data for load (lw) and store (sw) instructions. The processor interacts with this memory unit in the memory access phase, where:

    • Load instructions read data from memory.
    • Store instructions write data to memory. Since memory accesses are slower than register operations, modern implementations often use caches to speed up data retrieval.

MIPS Pipelining

Definition

Pipelining is a fundamental technique used in modern processors to enhance performance by enabling the overlapping execution of multiple instructions. Rather than executing one instruction at a time in a sequential manner, pipelining allows different parts of multiple instructions to be processed simultaneously.

This technique effectively exploits instruction-level parallelism, significantly improving the throughput of the processor. Throughput, in this context, refers to the number of instructions completed per unit of time.

The key idea behind pipelining is that the execution of an instruction can be divided into multiple stages, each responsible for a specific subset of operations required for instruction processing. Each stage requires only a fraction of the total execution time of the instruction.

By structuring the processor in this way, instructions are continuously fed into the pipeline, ensuring that multiple instructions are in progress at different execution stages at any given time.

Definition

A pipelined processor consists of a sequence of stages, each performing a portion of the instruction execution. These stages are connected in a streamlined manner, forming a pipeline through which instructions flow. Each instruction enters the pipeline at the first stage, progresses through subsequent stages, and finally exits upon completion.

The time required for an instruction to move from one stage to the next is dictated by the clock cycle time of the processor. The duration of a clock cycle is determined by the slowest pipeline stage, ensuring synchronization across all stages. Since each stage takes an equal amount of time to complete its task, the processor’s efficiency is maximized when all stages are balanced in terms of execution time. Ideally, if each pipeline stage has an identical execution time, the speedup gained by pipelining is directly proportional to the number of pipeline stages.

Example

For example, consider a non-pipelined processor where each instruction requires five cycles of 2 ns each, leading to a total execution time of 10 ns per instruction. In contrast, a pipelined processor with five stages of 2 ns each also requires 10 ns to complete a single instruction. However, because new instructions enter the pipeline every 2 ns, the processor completes one instruction every 2 ns instead of every 10 ns. This results in a theoretical speedup of 5×, assuming an ideal case without pipeline hazards.

The MIPS architecture adopts a five-stage pipeline, with each stage handling a distinct aspect of instruction execution.

By structuring the instruction execution in these five distinct stages, MIPS processors achieve efficient overlapping execution, ensuring that multiple instructions are in progress simultaneously, each at a different stage of execution.

Implementation of a Pipelined Processor

To effectively implement pipelining, a processor must be structured into five independent modules, each responsible for executing one of the pipeline stages. These modules are connected sequentially, forming a continuous flow of instruction processing. However, to prevent interference between instructions at different stages, inter-stage registers are introduced between each module. These registers store intermediate results, allowing each stage to operate independently.

Pipeline architecture with the inter-stage registers between each module

At any given moment, 5 different instructions can be simultaneously in different stages of execution. This parallel processing leads to significant performance improvements by increasing instruction throughput while maintaining a relatively simple control logic.

Assumptions

However, this model assumes ideal conditions where:

  • There are no data dependencies between consecutive instructions.
  • There are no branch or jump instructions that alter the sequential flow of execution.

In reality, such assumptions rarely hold, and hazards (such as data hazards, control hazards, and structural hazards) must be carefully managed to maintain efficiency.

Pipeline Hazards

Definition

A hazard is a condition that arises in a pipelined processor when an instruction cannot proceed to the next execution stage in the expected clock cycle due to a conflict or dependency. This prevents the smooth execution of instructions and causes delays, reducing the ideal speedup achieved by pipelining.

Hazards typically occur when instructions are closely spaced in the pipeline and their overlapping execution modifies the expected order of operand access. As a result, the next instruction may need to be delayed, leading to pipeline stalls (or bubbles)—clock cycles in which no useful work is performed.

There are three primary types of pipeline hazards:

  1. Structural Hazards: Resource conflicts that occur when multiple instructions require access to the same hardware component simultaneously.
  2. Data Hazards: Occur when an instruction depends on the results of a previous instruction that has not yet completed its execution.
  3. Control Hazards: Result from changes in the program’s control flow, such as branches and jumps, which affect the sequence of instruction execution.

Structural Hazards

Structural hazards arise when the processor hardware lacks sufficient resources to handle multiple simultaneous instruction operations. This typically occurs when different instructions require access to the same functional unit or memory system at the same time.

For example, in a simple processor design where instruction and data memory share the same physical memory unit, a structural hazard would occur if an instruction fetch (IF) stage tries to read an instruction from memory while a memory access (MEM) stage attempts to read or write data at the same time.

Caution

However, in MIPS architecture, structural hazards are generally avoided because:

  • Separate instruction and data memory: The Harvard architecture prevents conflicts between fetching instructions and accessing data.
  • Multiple read/write ports in the register file: MIPS provides two read ports and one write port, allowing different instructions to read and write registers simultaneously without conflict.

Data Hazards

A data hazard occurs when an instruction depends on the result of a previous instruction that has not yet completed. These hazards arise when pipeline stages attempt to access a register before the required data is available.

sub x2, x1, x3      # reg. x2 written by sub 
and x12, x2, x5     # 1° operand (x2) depends on sub 
or x13, x6, x2      # 2° operand (x2) depend on sub 
add x14, x2, x2     # 1° (x2) & 2° (x2) depend on sub 
sw x15,100(x2)      # base reg. (x2) depends on sub

Data hazards are classified into three types:

  1. Read-After-Write (RAW) Hazard
  2. Write-After-Read (WAR) Hazard
  3. Write-After-Write (WAW) Hazard

Read-After-Write (RAW) Hazard

A RAW hazard occurs when an instruction reads a register before a previous instruction has had a chance to write its result to that register. This happens because, in a pipelined execution, the register file is updated only in the write-back (WB) stage, which is later in the pipeline than the execution (EX) stage of subsequent instructions.

Example

Consider the following assembly code:

sub x2, x1, x3   # x2 = x1 - x3 (writes result in x2)
and x12, x2, x5  # Uses x2 before it is written

In this case, the and instruction attempts to read x2 before the sub instruction has completed writing to it, leading to a RAW hazard. This type of hazard is also known as a true data dependency, as the second instruction relies on the output of the first.

RAW hazards require forwarding (data forwarding or bypassing) or pipeline stalls to ensure correct execution.

Write-After-Read (WAR) Hazard

A WAR hazard occurs when an instruction writes to a register before a previous instruction has completed reading from it. In a classic five-stage pipeline, this is generally not an issue because register reads occur in the ID stage, while register writes happen in the WB stage, which occurs later.

However, WAR hazards can occur in more advanced architectures that allow out-of-order execution, where later instructions might execute earlier than expected.

Example

sub $t3, $t0, $t4  # Reads from $t0
add $t0, $t1, $t2  # Writes to $t0 before the previous 
				   # instruction finishes reading it

In this case, if the second instruction executes early and overwrites $t0, the first instruction may read the incorrect value.

Since MIPS follows in-order execution, WAR hazards are generally not a concern.

Write-After-Write (WAW) Hazard

A WAW hazard occurs when two instructions attempt to write to the same register in an incorrect order. This hazard arises in processors that support out-of-order execution, where later instructions might complete before earlier ones.

Example

add $t0, $t1, $t2  # Writes to $t0
sub $t0, $t3, $t4  # Also writes to $t0

If the second instruction completes execution before the first, the final value of $t0 may be incorrect.

Like WAR hazards, WAW hazards do not occur in a simple five-stage MIPS pipeline but can be present in architectures that support instruction reordering or superscalar execution.

Control Hazards (or Branch Hazards)

Control hazards, also known as branch hazards, occur when the pipeline encounters a branch or jump instruction, potentially altering the flow of execution. Since the processor fetches instructions sequentially, a branch instruction disrupts this pattern by conditionally or unconditionally changing the Program Counter (PC).

Example

beq $t0, $t1, LABEL  # Branch if $t0 == $t1
add $t2, $t3, $t4    # This instruction might be invalid 
					 # if the branch is taken

If the branch is taken, the instruction immediately following it in the pipeline is incorrect and must be discarded or replaced with the correct instruction from the target address. This results in wasted cycles.

MIPS Optimized Pipeline and Solutions to Data Hazards

To minimize data hazards, the MIPS pipeline optimizes register file access by splitting register operations into two stages within a single clock cycle:

  • Write occurs in the first half of the clock cycle (WB stage).
  • Read occurs in the second half of the clock cycle (ID stage).

This means that if an instruction needs to read a register that is being written by a previous instruction in the same cycle, the read operation still gets the updated value because the write completes before the read begins. This eliminates certain RAW hazards without requiring stalls.

However, if an instruction needs data from an earlier pipeline stage (e.g., EX or MEM), hazards may still occur and require additional techniques to resolve them.

There are two main approaches to mitigating data hazards in MIPS:

  1. Compilation Techniques (Software-Based Solutions)
  2. Hardware Techniques (Pipeline Enhancements)

Comparison of Techniques

MethodImplemented inAdvantagesDisadvantages
Instruction SchedulingCompilerAvoids hazards without extra hardwareRequires advanced compiler optimizations
NOP insertionCompilerSimple to implementWastes clock cycles, reduces efficiency
Forwarding (Bypassing)HardwareEliminates most RAW hazardsRequires extra control logic and multiplexers
Stalling (Pipeline Bubbling)HardwareEnsures correct executionWastes clock cycles, reduces performance

Compilation Techniques (Software-Based Solutions)

The compiler can attempt to rearrange instructions to avoid hazards by:

  1. Inserting NOPs (No-Operation Instructions):

    • If a data dependency exists, the compiler inserts NOP instructions to delay execution until the correct data is available.
    • This technique is simple but inefficient, as it wastes clock cycles.

  2. Instruction Scheduling (Reordering Instructions):

    • Instead of inserting NOPs, the compiler can rearrange instructions to insert independent instructions between dependent ones.
    • This keeps the pipeline filled with useful work while waiting for the dependent data.

Hardware Techniques (Pipeline Enhancements)

MIPS processors also include hardware techniques to handle data hazards, primarily through forwarding and stalls. These techniques are implemented in the processor’s control logic and data path to ensure correct execution without relying solely on the compiler.

Forwarding (Data Bypassing)

Definition

Forwarding (also called bypassing) allows an instruction to use an intermediate result from a pipeline register before it is written back to the register file. This prevents unnecessary stalls.

Instead of waiting for WB to update the register file, data is directly forwarded from pipeline registers (EX/MEM or MEM/WB) to the ALU or another stage where it is needed. This requires extra multiplexers at the ALU inputs to select forwarded data instead of reading from the register file.

  1. MEM-to-EX Forwarding

    • The result from MEM/WB is forwarded to the ALU input of the next instruction.
    • Used when an instruction depends on the result of the previous instruction.
    sub x2, x1, x3     # x2 = x1 - x3
    and x12, x2, x5    # Uses x2 immediately (MEM-to-EX needed)
  2. MEM-to-MEM Forwarding

    • Used for LOAD and STORE instructions when the memory operation is dependent on another memory operation.
    • Eliminates the need for stalls by forwarding the memory result directly.
    lw x2, 0(x1)     # Load data into x2
    sw x2, 4(x3)     # Store the same data into memory

    • Without forwarding, sw would stall until lw finishes WB.
    • With MEM-to-MEM forwarding, the lw result is directly forwarded to sw without waiting.
  3. MEM-to-ID Forwarding

    • The result from MEM stage is forwarded back to the ID stage instead of waiting for WB.
    • Used when an instruction in the ID stage depends on a memory result before it is written back.
    lw x2, 0(x1)     # Load into x2
    add x4, x2, x3   # Uses x2 (MEM-to-ID needed)

    MEM-to-ID forwarding prevents a stall by allowing x2 to be used before WB.

Stalling (Pipeline Bubbling)

If forwarding is not possible, the processor stalls the pipeline by inserting NOP-like bubbles until the data is available.

  • A pipeline stall delays instruction execution without discarding instructions.
  • A stall typically occurs when loading data from memory since forwarding cannot bypass memory delays.

Performance Trade-Off:

  • Forwarding is preferred since it avoids wasted cycles.
  • Stalls are a last resort when forwarding is not an option (e.g., Load-Use Hazards).

Performance Evaluation of the MIPS Pipeline

Pipelining is a fundamental technique used in modern processors to enhance instruction throughput, which refers to the number of instructions executed per unit of time.

However, it is important to note that pipelining does not reduce the execution latency of a single instruction. In fact, due to various pipeline inefficiencies, the latency of individual instructions may even increase slightly.

This is primarily caused by two factors: stage imbalance and pipeline overhead.

The imbalance among pipeline stages arises because the processor’s clock cycle time is constrained by the slowest pipeline stage. If one stage requires more time than the others, it dictates the overall cycle time, preventing faster stages from completing their tasks sooner. On the other hand, pipeline overhead is introduced by the presence of pipeline registers, which store intermediate values between pipeline stages. These registers introduce additional delays due to setup and hold times, as well as clock skew, which refers to slight variations in timing when distributing the clock signal across different parts of the pipeline.

Furthermore, in a pipelined processor, all instructions are expected to complete execution in the same number of cycles, even if certain instructions do not require every stage of the pipeline. This uniform execution constraint can lead to inefficiencies, as some instructions may spend unnecessary time passing through stages that do not contribute to their execution.

To quantitatively evaluate pipeline performance, several key metrics are defined. Let us consider three fundamental parameters:

  1. Instruction Count (): The total number of instructions executed by the program.
  2. Clock Cycles per Instruction (): The average number of clock cycles required to execute one instruction.
  3. Instruction Count per Cycle (): The reciprocal of , indicating how many instructions are completed per clock cycle.

Using these parameters, we define the following fundamental performance equations:

  • Total number of clock cycles required for execution:

    The additional 4 cycles account for the pipeline startup latency, which occurs because the pipeline must be filled before it can reach full operational capacity.

  • Clock Cycles Per Instruction ():

    This equation expresses CPI as a function of the total stall cycles. Ideally, a fully efficient pipeline would achieve , but in reality, stalls due to hazards increase this value.

  • Million Instructions Per Second ():

    This metric represents the execution speed of a processor, where is the clock frequency. A higher MIPS value generally indicates better performance, but it is highly dependent on , which is affected by pipeline inefficiencies.

Performance Analysis in Loops

When evaluating performance for iterative loops, where instructions repeat multiple times, we analyze execution based on the number of iterations () and instructions per iteration (). If each iteration requires stalls, the performance metrics per iteration are:

  • Instruction Count per iteration:
  • Clock Cycles per iteration:
  • CPI per iteration:
  • MIPS per iteration:

When considering a large number of iterations, the performance stabilizes, allowing us to compute the asymptotic performance as :

  • Total instruction count:
  • Total number of clock cycles:
  • Asymptotic CPI:

As the number of iterations increases, the impact of pipeline startup latency (the extra 4 cycles) diminishes, and the asymptotic CPI approaches , showing that pipeline stalls remain the dominant factor.

Pipeline Performance Bottlenecks

In an ideal scenario, the pipeline would achieve a of 1, meaning that a new instruction completes every cycle. However, various types of pipeline hazards introduce stall cycles, causing the actual to be greater than 1. The relationship can be expressed as:

The additional stall cycles per instruction arise from different types of pipeline hazards:

  1. Data Hazards: Occur when an instruction depends on the result of a previous instruction that has not yet completed. Forwarding (bypassing) can mitigate some of these hazards, but load-use dependencies often introduce stalls.
  2. Control Hazards: Arise when the processor encounters a branch instruction and must determine the correct next instruction to execute. Techniques like branch prediction help reduce these stalls.
  3. Structural Hazards: Occur when hardware resources (e.g., memory access units, execution units) are insufficient to handle multiple instructions simultaneously.
  4. Memory Stalls: Arise from delays in fetching data from memory, which can significantly impact pipeline performance if cache misses occur frequently.

Each of these factors contributes to increasing the stall cycles per instruction, reducing the overall efficiency of the pipeline.