Think of a car production line - at each stage a component is added to the car. At a stage in the production line, the person has run out of parts. The production line is ‘stalled’ - no further work can be done until that stage has parts again. In the case of the processor, it might be waiting for a memory access to complete. This stops other potential work being done.
With the same production line concept it is determined no one is buying the cars. There are two choices, finish the cars that are on the production line and throw them away or cut your losses and just clear out all the unfinished cars and dump them - this is a ‘flush’. In the case of the processor, this might be a jump instruction. All the work that was following that instruction is wasted. The processor will jump to a new location and begin to fill up the pipeline again.
Either a stall or a flush hurts performance as potential clock cycles do not yield useful work. Whether it be a car production line or a pipelined processor, a stall or flush is something you want to avoid, so you devise strategies for this.
Suppose there's a data dependency in the pipeline, i.e. an instruction needs data from the result of a previous instruction. So you need to stall this instruction till the previous one completes to resolve the data hazard. Stalling is done by inserting "No Ops" i.e. instructions that do no work. This keeps the processor idle and decreases the throughput.
Suppose there's a conditional branch instruction in the program. This instruction is moving forward in the pipeline. If it's a 5 stage classic RISC pipeline, let's suppose this instruction reaches the 3rd stage.
The stages of the pipeline behind this instruction are executing the instructions following the branch statement. Depending on the outcome of the execution of the branch statement, the instructions after the branch are either executed as required by the program i.e. the branch is not taken so they have to be executed, or are executed even though they are not required by the program i.e. the branch is taken so they do not have to be executed.
In the second case, you are executing instructions that were not required by the program, so you need to flush the pipeline to remove the wrong data in the pipeline stages. This reduces the throughput.
Pipeline stalling and flushing can be reduced using Out-of-Order execution and branch prediction algorithms.
Data hazards which cause pipeline stalling can also be dealt using pipeline forwarding.
You need a book before you can proceed with your project; so you order it from Amazon.
Amazon will deliver it tomorrow; until the postman arrives tomorrow, there is nothing you can do. This is a stall.
Amazon is out of stock. Until it is re-printed, all you can do is put that project aside, (commit everything you have done so far) and start a new project. This is a flush.