Issue Inorder

From Msim

Jump to: navigation, search

This article refers to the use of the command line parameter "-issue:inorder <bool>"

Usage

Single core: To enable:

-issue:inorder true

To disable (default):

-issue:inorder false

This is a per-core option, not a per-thread option.

Multiple core: To enable:

-issue:inorder_X true, where X is the core number (starting from 0).
The following enable for the first and second core.
-issue:inorder_0 true
-issue:inorder_1 true


Description

The inorder issue flag (see cmp.h, core_t::inorder_issue), directs the core to stall register rename of an instruction (from a particular thread/context) until:

- The prior instruction has all of its register source ready
- This implies that the prior instruction has been issued (but may not actually be the case)
- The prior instruction is ready for issue will be issued before the current instruction


This is handled by keeping track of the last instruction that was renamed (and consequently entered the ROB/LSQ).

- When an instruction is renamed, its ROB entry is pointed to by the pointer "last_op" (see smt.h, context::last_op). This pointer is private for each thread/context. 
- If the instruction generates an LSQ entry, point to the LSQ entry instead - this more accurately represents the readiness of that instruction.
- A newly renamed instruction will replace the old "last_op" instruction.
- "last_op" is lazily handled, it is not cleared when the instruction it refers to is completed/evicted/etc. When trying to rename, if "last_op" points to an instruction that is not yet ready, we then verify that the instruction "last_op" points to is valid. If not valid, the stall does not occur.

Fixes

In all versions of M-Sim 3.0 released before July 2009, inorder issuing did not work correctly. This was due to the possibility of "last_op" pointing to a deallocated ROB (or LSQ) entry that would return false when checked if its register sources were ready. This bug came about with the removal of the RS_VALID macro that would check if "last_op" was valid (RS_VALID was removed when implementing rollback mechanisms in the simulator).
An additional bug was that "last_op" was only pointing to instructions that generated an LSQ instruction, instead of all instructions.
Prior code did not ensure that "last_op" was valid (from sim-outorder.c):

//if issuing in-order, block until last op issues if inorder issue
if(cores[core_num].inorder_issue && (contexts[disp_context_id].last_op.rs && !all_operands_ready(contexts[disp_context_id].last_op.rs)))
{
 //stall until last operation is ready to issue
 contexts_left.erase(contexts_left.begin()+current_context);
 if(contexts_left.empty())
  break;
 current_context%=contexts_left.size();
 continue;
}

This can be checked with the following replacement code:

//if issuing in-order, block until last op issues if inorder issue
if(cores[core_num].inorder_issue && (contexts[disp_context_id].last_op.rs && !all_operands_ready(contexts[disp_context_id].last_op.rs)))
{
 //If last_op is no longer valid, ignore this
 if(contexts[disp_context_id].ROB_num != 0)
 {
  unsigned int index = (contexts[disp_context_id].last_op.rs - &contexts[disp_context_id].ROB[0]);
  unsigned int upper = contexts[disp_context_id].ROB_head + contexts[disp_context_id].ROB_num - 1;
  if(index<contexts[disp_context_id].ROB_head)
  {
   index+=contexts[disp_context_id].ROB.size();
  }
  if((index >= contexts[disp_context_id].ROB_head) && (index <= upper))
  {
   //stall until last operation is ready to issue
   contexts_left.erase(contexts_left.begin()+current_context);
   if(contexts_left.empty())
    break;
   current_context%=contexts_left.size();
   continue;
  }
 }
 contexts[disp_context_id].last_op = RS_link((ROB_entry *)NULL);
}

We must also ensure that all instructions are pointed to by last_op
Add the bolded code to sim-outorder.c

rs->L1_miss = rs->L2_miss = rs->L3_miss = 0;
contexts[disp_context_id].last_op = RS_link(rs);
Personal tools