A hazard is a potential problem that can cause a pipelined processor to obtain incorrect computing result. There are typically three types of hazards: data hazards, structural hazards, and branching hazards (control hazards).
Data Hazard
Data hazard can happen when a CPU tries to simultaneously execute multiple instructions which exhibit data dependence
RAW - Read After Write
A RAW Data Hazard refers to a situation where we refer to a result that has not yet been calculated, for example:
i1. R2 <- R1 + R3
i2. R4 <- R2 + R3
The first instruction is calculating a value to be saved in register 2, and the second is going to use this value to compute a result for register 4. However, in a pipeline, when we fetch the operands for the 2nd operation, the results from the first will not yet have been saved, and hence we have a data dependency.
We say that there is a data dependency with instruction 2, as it is dependent on the completion of instruction 1.
i1. R2 <- R1 + R3
i2. R4 <- R2 + R3
The first instruction is calculating a value to be saved in register 2, and the second is going to use this value to compute a result for register 4. However, in a pipeline, when we fetch the operands for the 2nd operation, the results from the first will not yet have been saved, and hence we have a data dependency.
We say that there is a data dependency with instruction 2, as it is dependent on the completion of instruction 1.
WAR - Write After Read
A WAR Data Hazard represents a problem with concurrent execution, for example:
i1. R4 <- R1 + R3
i2. R3 <- R1 + R2
If we are in a situation that there is a chance that i2 may be completed before i1 (i.e. with concurrent execution) we must ensure that we do not store the result of register 3 before i1 has had a chance to fetch the operands.
i1. R4 <- R1 + R3
i2. R3 <- R1 + R2
If we are in a situation that there is a chance that i2 may be completed before i1 (i.e. with concurrent execution) we must ensure that we do not store the result of register 3 before i1 has had a chance to fetch the operands.
WAW - Write After Write
A WAW Data Hazard is another situation which may occur in a concurrent execution environment, for example:
i1. R2 <- R1 + R2
i2. R2 <- R4 + R7
We must delay the WB (Write Back) of i2 until the execution of i1.
i1. R2 <- R1 + R2
i2. R2 <- R4 + R7
We must delay the WB (Write Back) of i2 until the execution of i1.
Solutions
1) data forwarding: some data hazards can't be solved by it. Ex. lw instruction in MIPS architecture
2) pipeline stall: Ex. for lw instruction
3) instruction scheduling: Compiler should do that. Ex.
2) pipeline stall: Ex. for lw instruction
3) instruction scheduling: Compiler should do that. Ex.
lw R1, 1000(R2)
lw R3, 2000(R2)
add R4, R1, R3
lw R1, 3000(R2)
add R6, R4, R1
sw R6, 1000(R2)
lw R3, 2000(R2)
add R4, R1, R3
lw R1, 3000(R2)
add R6, R4, R1
sw R6, 1000(R2)
change to
lw R1, 1000(R2)
lw R3, 2000(R2)
lw Rn, 3000(R2) // swap "lw" and "add"
add R4, R1, R3
add R6, R4, Rn
sw R6, 1000(R2)
lw R3, 2000(R2)
lw Rn, 3000(R2) // swap "lw" and "add"
add R4, R1, R3
add R6, R4, Rn
sw R6, 1000(R2)
Structural Hazard
A structural hazard occurs when a part of the processor's hardware is needed by two or more instructions at the same time. A structural hazard might occur, for instance, if a program were to execute a branch instruction followed by a computation instruction. Because they are executed in parallel, and because branching is typically slow (requiring a comparison, program counter-related computation, and writing to registers), it is quite possible (depending on architecture) that the computation instruction and the branch instruction will both require the ALU (arithmetic logic unit) at the same time.
Branch Harzard
Branching hazards (also known as control hazards) occur when the processor is told to branch - i.e., if a certain condition is true, then jump from one part of the instruction stream to another - not necessarily to the next instruction sequentially. In such a case, the processor cannot tell in advance whether it should process the next instruction (when it may instead have to move to a distant instruction).
This can result in the processor doing unwanted actions.
1) stall pipeline: until we know its taken or non-taken
2) predict taken or non-taken: and fill the pipeline with associated instruction. Compiler uses like taken and unlikely taken to denote the branch instruction, and if its found not the case, CPU cancel or nullify the delayed slot instruction.
3) delayed branch: Fill instruction that will be valid no matter branch is taken or non-taken into pipeline. Compiler should do that.
4) hardware branch predictor: Its dynamic branch prediction. static branch prediction is done by compiler.
This can result in the processor doing unwanted actions.
1) stall pipeline: until we know its taken or non-taken
2) predict taken or non-taken: and fill the pipeline with associated instruction. Compiler uses like taken and unlikely taken to denote the branch instruction, and if its found not the case, CPU cancel or nullify the delayed slot instruction.
3) delayed branch: Fill instruction that will be valid no matter branch is taken or non-taken into pipeline. Compiler should do that.
4) hardware branch predictor: Its dynamic branch prediction. static branch prediction is done by compiler.
沒有留言:
張貼留言