Wed, 15 Apr 2015, 20:54


A student writes:

> Dear Professor,
>   In today's class, you say we will handle most exception immediately even
> in pipeline/Out-of-Order machine. However, I believe this is a bad idea:
>   First of all, if we have branch prediction, then we may get an exception
> from a mispredicted instruction and if we handle it immediately we will
> get a false alarm because this instruction may never be executed.
>   Second, handling exception immediately in OoO machine may violate
> precise exception.
>   Also, in most literature I've read exceptions are handled in the
> retirement stage when we know for sure this instruction will be executed
> and we can also provide architectural states.
> 
> Thanks,
> <>

Thank you!  Shame on me!  What was I thinking?  You are absolutely right that
we would never want to take an exception until we know that the instruction
is in the correct flow of instructions.  And your example is an excellent one:

ADD R1,R2,R3
BRz X
LD R4, A

We predict the branch is not taken, and A causes a page fault.  We would not
want to take the page fault until we confirm the prediction.  Suppose the
branch is actually taken (i.e., we mispredicted).  Then we would not execute 
the LD, and therefore no page fault should occur.  Exceptions take a lot of
time and should only be done when we know that the instruction is in the
correct flow.

So if not immediately, when should the exception be taken?  I do not like
saying "in the retirement stage" since the faulting instruction never 
legitimately gets to the retirement stage.  ...although I can certainly 
believe that there are many write-ups that call it the retirement stage.

In fact, we could (and many machines do) use the expedient when an instruction
faults, of updating the ROB entry in two ways: with a flag which says the 
corresponding instruction must take an exception.  And the execution flag 
saying the instruction has completed execution (even though it hasn't - and 
can't), and is therefore ready for retirement.  Then, when the instruction 
immediately before it retires, this instruction is ready for retirement.  
At that point, since the exception flag is raised, the exception will be 
taken.  Perhaps this is the easier way to think about it, and one could say
this action is done in the retirement stage.

I would simply rather say: We take the exception when the instruction 
immediately preceding it in the dynamic instruction stream retires.

In my example above, assume the LD generates a page fault.  When the BRz
instruction retires, we can then take the page fault for the LD instruction.

Two possibilities:

1. The branch not taken is confirmed, which enables the BRz instruction to
retire.  Once BRz has retired, we have the desired consistent state for 
precise exceptions, and the page fault is taken.

2. The branch not taken is a misprediction.  When that happens, everything in
the reorder buffer after the BRz is trashed, and the processor starts down the
correct path (starting with the instruction at X).  Since the LD is in the
reorder buffer after the BRz, it is trashed, and the page fault is not taken.

One more thing:  Suppse we have the following code:

ADD R1,R2,R3
BRz X
ADD R6,R7,R8
LD R4, A

Again, the LD causes a page fault.  When do we take the exception?
Answer: As soon as ADD R6,R7,R8 retires.  We need to do that to take
the precise exception.

Sorry for the confusion in class today.  I must have been sound asleep
when I made the comment.

Good luck on the second midterm.

Yale Patt