Example #1
0
/* Stride Prefetcher */
void stride_prefetcher(struct cache_t *cp, md_addr_t addr) {
#if 0
  int counter = 0;
while (pc) {
    if (pc & 1)
        printf("1");
    else
        printf("0");

    if (counter == 0 && pc&1 != 0 || counter == 1 && pc&1 != 0 || counter == 2 && pc&1 != 0) assert(0);
    pc >>= 1;
    counter++;
}
printf("\n");
#endif

#if 1
  md_addr_t pc = get_PC();
  // The last three bits do not change
  unsigned int index = (pc >> 3) & (cp->prefetch_type - 1);
  unsigned int tag = (pc >> (log_base2(cp->prefetch_type) + 3));
#endif

  // Scenario 1
  if (cp->rpt[index].tag != tag) {
    cp->rpt[index].tag = tag;
    cp->rpt[index].prev_addr = addr;
    cp->rpt[index].stride = 0;
    cp->rpt[index].state = initial;
    cp->rpt[index].is_neg = 0;
  } else {
  // Scenario 2
    md_addr_t prev_addr = cp->rpt[index].prev_addr;
    md_addr_t new_stride = MAX(addr, prev_addr) - MIN(addr, prev_addr);
    int new_is_neg = prev_addr > addr ? 1 : 0;
    int stride_condition = new_stride == cp->rpt[index].stride && new_is_neg == cp->rpt[index].is_neg;
    assert(stride_condition == 1 || stride_condition == 0);

    cp->rpt[index].state = update_state(cp->rpt[index].state, stride_condition);

    if (!stride_condition && (cp->rpt[index].state == transient || cp->rpt[index].state== no_prediction)) {
      cp->rpt[index].stride = new_stride;
      cp->rpt[index].is_neg = new_is_neg;
    }
    cp->rpt[index].prev_addr = addr;
    if (cp->rpt[index].state != no_prediction) {
      if (cp->rpt[index].is_neg) {
        prefetch(cp, addr - cp->rpt[index].stride);
      } else {
        prefetch(cp, addr + cp->rpt[index].stride);
      }
    }
  }
}
Example #2
0
/* Open Ended Prefetcher */
void open_ended_prefetcher(struct cache_t *cp, md_addr_t addr) {
  md_addr_t pc = get_PC();
  // The last three bits do not change
  unsigned int index = (pc >> 3) & (DEFAULT_RPT_SIZE - 1);
  unsigned int tag = (pc >> (log_base2(DEFAULT_RPT_SIZE) + 3));
  assert(index >= 0 && index < rdim);

  //unsigned int hist_index = (cp->prev_hist_addr & (rdim - 1));
  //unsigned int hist_tag = cp->prev_hist_addr >> log_base2(rdim);

  // Scenario 1
  if (cp->rpt[index].tag != tag) {
    cp->rpt[index].tag = tag;
    cp->rpt[index].prev_addr = addr;
    cp->rpt[index].stride = 0;
    cp->rpt[index].state = initial;
    cp->rpt[index].is_neg = 0;
    history_push_back(cp, addr, index, tag);
    return;
    //if (cp->prev_hist_addr != 0)
      //history_push_back(cp, addr, hist_index, hist_tag);
  } else {
  // Scenario 2
    md_addr_t prev_addr = cp->rpt[index].prev_addr;
    md_addr_t new_stride = MAX(addr, prev_addr) - MIN(addr, prev_addr);
    int new_is_neg = prev_addr > addr ? 1 : 0;
    int stride_condition = new_stride == cp->rpt[index].stride && new_is_neg == cp->rpt[index].is_neg;
    assert(stride_condition == 1 || stride_condition == 0);

    cp->rpt[index].state = update_state(cp->rpt[index].state, stride_condition);

    if (!stride_condition && (cp->rpt[index].state == transient || cp->rpt[index].state== no_prediction)) {
      cp->rpt[index].stride = new_stride;
      cp->rpt[index].is_neg = new_is_neg;
    }
    cp->rpt[index].prev_addr = addr;


    if (cp->rpt[index].state != no_prediction) {
      if (cp->rpt[index].is_neg) {
        prefetch(cp, addr - cp->rpt[index].stride);
      } else {
        prefetch(cp, addr + cp->rpt[index].stride);
      }
    } else {
      int i;
      for (i = cp->idx[index] - 2; i >= 0; i--) {
        if (cp->ht[index][i] == addr) {
          prefetch(cp, cp->ht[index][i + 1]);
          break;
        }
      }

      //if (cp->idx[hist_index] - 1 >= 0) {
        //prefetch(cp, cp->ht[hist_index][cp->idx[hist_index] - 1]);
      //}
    }
    //if (cp->prev_hist_addr != 0)
      //history_push_back(cp, addr, hist_index, hist_tag);
  }
  history_push_back(cp, addr, index, tag);
  //cp->prev_hist_addr = addr;
}
Example #3
0
/* Stride Prefetcher */
void stride_prefetcher(struct cache_t *cp, md_addr_t addr) {
  int i;
  md_addr_t pc_tag = get_PC();
  assert((7 & pc_tag) == 0);
  pc_tag = get_PC() >> 3;
  md_addr_t prefetch_addr = 0;

  int rpt_set_shift = log2(cp->prefetch_type);
  int rpt_idx = pc_tag & ((1 << rpt_set_shift) - 1);

  if (rpt.size() > cp->prefetch_type)
    fatal("RPT table went over the size limit \n");
  if (rpt_idx > cp->prefetch_type)
    fatal("RPT index went over the size limit \n");
  

  prediction_t * match_entry = NULL;
  bool match = false;
  if(rpt[rpt_idx].tag == pc_tag)
  {
     match = true;
     match_entry = &rpt[rpt_idx];
  }

  //no matching PC tag; assign a new entry
  if (!match) {
    prediction_t n_entry;
    n_entry.tag = pc_tag;
    n_entry.state = INITIAL;
    n_entry.prev_addr = addr;
    n_entry.stride = 0;
    rpt[rpt_idx] = n_entry;
  } else {
    int stride = (int)addr - (int)match_entry->prev_addr;
    switch(match_entry->state) {
      case INITIAL:
        if(stride == match_entry->stride) {
          prefetch_addr = (md_addr_t)((int)addr + (int)match_entry->stride);
          match_entry->state = STEADY;
        } else {
          match_entry->state = TRANSIENT;
          match_entry->stride= stride;
        }
        break;
      case TRANSIENT:
        if(stride == match_entry->stride) {
          match_entry->state = STEADY;
          prefetch_addr = (md_addr_t)((int)addr + (int)match_entry->stride);
        } else {
          match_entry->state = NO_PRED;
          match_entry->stride= stride;
        }
        break;
      case STEADY:
        if(stride != match_entry->stride) {
          match_entry->state = INITIAL;
        } else {
          prefetch_addr = (md_addr_t)((int)addr + (int)match_entry->stride);
        }
        break;
      case NO_PRED:
        if(stride == match_entry->stride) {
          match_entry->state = TRANSIENT;
        } else {
          match_entry->stride= stride;
        }
        break;
    }
    match_entry->prev_addr = addr; 
  }
  if (prefetch_addr != 0)
    fetch_cache_blk(cp, prefetch_addr);

}
Example #4
0
File: run.c Project: Suckzoo/CS311
void process_instruction(){
	instruction *inst;
	int i;      // for loop

	/* pipeline */
	CURRENT_STATE.PIPE[0] = CURRENT_STATE.PC;
	CURRENT_STATE.PIPE[1] = CURRENT_STATE.IF_ID.PC;
	CURRENT_STATE.PIPE[2] = CURRENT_STATE.ID_EX.PC;
	CURRENT_STATE.PIPE[3] = CURRENT_STATE.EX_MEM.PC;
	CURRENT_STATE.PIPE[4] = CURRENT_STATE.MEM_WB.PC;

	mem_wb_reg MEM_WB;
	ex_mem_reg EX_MEM; 
	id_ex_reg ID_EX;
	memset(&MEM_WB, 0, sizeof(mem_wb_reg));
	memset(&EX_MEM, 0, sizeof(ex_mem_reg));
	memset(&ID_EX, 0, sizeof(id_ex_reg));
	if(CURRENT_STATE.PIPE[4]) run_WB();
	if(CURRENT_STATE.PIPE[3]) MEM_WB = run_MEM();
	if(CURRENT_STATE.MEM_bubble_count)
	{
		if(DEBUG) printf("MEM BUBBLE\n");
		CURRENT_STATE.MEM_bubble_count--;
		CURRENT_STATE.pc_hold = 1;
	}
    else if(CURRENT_STATE.IF_ID_flush_count)
    {
        CURRENT_STATE.MEM_WB = MEM_WB;
        ex_mem_reg rr;
        memset(&rr, 0, sizeof(rr));
        CURRENT_STATE.EX_MEM = rr;
        id_ex_reg rrr;
        memset(&rrr, 0, sizeof(rrr));
        CURRENT_STATE.ID_EX = rrr;
        CURRENT_STATE.IF_ID = run_BUBBLE();
        CURRENT_STATE.IF_ID_flush_count = 0;
        CURRENT_STATE.flushed = 1;
    }
	else
	{
		if(CURRENT_STATE.PIPE[2]) EX_MEM = run_EX();
		// if(CURRENT_STATE.EX_bubble_count)
		// {
		// 	if(DEBUG) printf("EX BUBBLE\n");
		// 	CURRENT_STATE.MEM_WB = MEM_WB;
		// 	CURRENT_STATE.EX_bubble_count--;
		// 	CURRENT_STATE.pc_hold = 1;
		// }
        // 얘가 여기 있으면 안됨. 파이프라인은 다 같이 도는거기 때문에 이번 결과를 적용시켜버리면 안되지.
		// else if(CURRENT_STATE.IF_ID_flush_count)
		// {
		// 	CURRENT_STATE.MEM_WB = MEM_WB;
		// 	CURRENT_STATE.EX_MEM = EX_MEM;
		// 	id_ex_reg rrr;
		// 	memset(&rrr, 0, sizeof(rrr));
		// 	CURRENT_STATE.ID_EX = rrr;
		// 	CURRENT_STATE.IF_ID = run_BUBBLE();
		// 	CURRENT_STATE.IF_ID_flush_count = 0;
  //           CURRENT_STATE.flushed = 1;
		// }
	
		if(CURRENT_STATE.PIPE[1]) {
			ID_EX  = run_ID();
			// CURRENT_STATE.PC = ID_EX.NPC;
		}
		if_id_reg IF_ID = run_IF();
		// 포워드 없을때 기다리는거! EX버블은 아닙니다!
		if(CURRENT_STATE.EX_bubble_count){
			CURRENT_STATE.MEM_WB = MEM_WB;
			CURRENT_STATE.EX_MEM = EX_MEM;
			CURRENT_STATE.ID_EX = ID_EX;
			CURRENT_STATE.pc_hold = 1;
			CURRENT_STATE.EX_bubble_count--;
		}
		else{
	        // branch가 taken되면 IF_ID에 들어가있는걸 비운다!
	        if(!nobp_set && CURRENT_STATE.branchhuh){
	            IF_ID = run_BUBBLE();
	        }
			if(CURRENT_STATE.bubble_count)
			{
	            if(DEBUG) printf("bubble1\n");
	            CURRENT_STATE.pc_hold = 1;
				IF_ID = run_BUBBLE();
				CURRENT_STATE.bubble_count--;
			}
			if(ID_EX.cMemRd 
					&& (IF_ID.instr.r_t.r_i.rs == ID_EX.rt 
						|| IF_ID.instr.r_t.r_i.rt == ID_EX.rt)) // Load-use XXX 포워드 없을땐?
																// IF에 잡아두면 안되네 밀어줘야하네!
			{
	            CURRENT_STATE.pc_hold = 1;
	            if(DEBUG) printf("bubble2: load-use\n");
				IF_ID = run_BUBBLE();
			}	
			if(ID_EX.cALUOp == 7 || ID_EX.cALUOp == -1) // Jump
			{
	            // CURRENT_STATE.pc_hold = 1;
	            if(DEBUG) printf("bubble3\n");
				IF_ID = run_BUBBLE();
			}
			// if(nobp_set && (ID_EX.cALUOp == 3 || ID_EX.cALUOp == 4)) // nobp!
			if(nobp_set && (ID_EX.cBranch))
			{
	            if(DEBUG) printf("bubble4\n");
				IF_ID = run_BUBBLE();
				CURRENT_STATE.bubble_count = 2;
			}

	        // bubble + flush..? 


			//TODO: what if branch f****d up?
			CURRENT_STATE.IF_ID = IF_ID;
			CURRENT_STATE.ID_EX = ID_EX;
			CURRENT_STATE.EX_MEM = EX_MEM;
			CURRENT_STATE.MEM_WB = MEM_WB;
		}
	}
	CURRENT_STATE.PC = get_PC();
	// printf("PC : %x, end point : %x\n", CURRENT_STATE.PC, MEM_REGIONS[0].start + (NUM_INST * 4) );
	if (CURRENT_STATE.PC < MEM_REGIONS[0].start || 
		( CURRENT_STATE.PC >= (MEM_REGIONS[0].start + (NUM_INST * 4)) &&
			!CURRENT_STATE.IF_ID.PC&&!CURRENT_STATE.ID_EX.PC&&
			!CURRENT_STATE.EX_MEM.PC&&!CURRENT_STATE.MEM_WB.PC)
        || (num_inst_set && !num_inst))
		RUN_BIT = FALSE;
	else
	{
		//otherwise, why does it continue?
		//int ii;
		//for(ii=0;ii<5;ii++)
		//{
		//	//if(CURRENT_STATE.PIPE[ii]) break;
		//	printf("PIPE[%d]: %x\n",ii, CURRENT_STATE.PIPE[ii]);
		//}
		//if(1)
		//{
		//	printf("it's because: \n");
		//	printf("CURRENT_STATE.PC < MEM_REGIONS[0].start: %d\n",
		//			CURRENT_STATE.PC < MEM_REGIONS[0].start);
		//	printf("CURRENT_STATE.PC >= (MEM_REGIONS[0].start + (NUM_INST * 4)): %d\n",
		//			CURRENT_STATE.PC >= (MEM_REGIONS[0].start + (NUM_INST * 4)));
		//	printf("!CURRENT_STATE.IF_ID.PC: %d\n",
		//			!CURRENT_STATE.IF_ID.PC);
		//	printf("!CURRENT_STATE.ID_EX.PC: %d\n",
		//			!CURRENT_STATE.ID_EX.PC);
		//	printf("!CURRENT_STATE.EX_MEM.PC: %d\n",
		//			!CURRENT_STATE.EX_MEM.PC);
		//	printf("!CURRENT_STATE.MEM_WB.PC: %d\n",
		//			!CURRENT_STATE.MEM_WB.PC);
		//	printf("num_inst_set: %d\n",
		//			num_inst_set);
		//	printf("!num_inst: %d\n",
		//			!num_inst);
		//}
	}
}
Example #5
0
/* Open Ended Prefetcher */
void open_ended_prefetcher(struct cache_t *cp, md_addr_t addr) {
  /* ECE552 Assignment 4 - BEGIN CODE */
  float accuracy = (float)cp->prefetch_useful_cnt / (float) cp->prefetch_cnt;
  float polution = (float)cp->prefetch_misses / (float) cp->misses;

  //High-accuracy 
  if(accuracy > 0.75)
  {
    //low polution
    if (polution < 0.01) {
      if(cp->prefetch_aggr < 5) {
         cp->prefetch_aggr += 1;
      }
    } else {
      if(cp->prefetch_aggr > 0) {
         cp->prefetch_aggr -= 1;
      }
    }
  }
  //Medium-accuracy
  else if (accuracy > 0.4) 
  {
    //poluting
    if (polution >= 0.01) {
      if(cp->prefetch_aggr > 0) {
         cp->prefetch_aggr -= 1;
      }
    } 
  }
  //Low-accuracy
  else {
    //poluting
    if (polution >= 0.01) {
      if(cp->prefetch_aggr > 0) {
         cp->prefetch_aggr -= 1;
      }
    } 
  }

  md_addr_t pc_tag = get_PC();
  assert((7 & pc_tag) == 0);
  pc_tag = get_PC() >> 3;
  md_addr_t prefetch_addr = 0;

  int set_shift = log2(256);
  int p_idx = pc_tag & ((1 << set_shift) - 1);

  if (p_idx >= 256)
    fatal("open-ended: index went over the size limit \n");
  
  prediction_t * match_entry = NULL;
  bool match = false;
  if(p_table[p_idx].tag == pc_tag)
  {
     match = true;
     match_entry = &p_table[p_idx];
  }

  //no matching PC tag; assign a new entry
  if (!match) {
    prediction_t n_entry;
    n_entry.tag = pc_tag;
    n_entry.state = INITIAL;
    n_entry.prev_addr = addr;
    n_entry.stride = 0;
    p_table[p_idx] = n_entry;
  } else {
    int stride = (int)addr - (int)match_entry->prev_addr;
    switch(match_entry->state) {
      case INITIAL:
        if(stride == match_entry->stride) {
          prefetch_addr = (md_addr_t)((int)addr + (int)match_entry->stride);
          match_entry->state = STEADY;
        } else {
          match_entry->state = TRANSIENT;
          match_entry->stride= stride;
        }
        break;
      case TRANSIENT:
        if(stride == match_entry->stride) {
          match_entry->state = STEADY;
          prefetch_addr = (md_addr_t)((int)addr + (int)match_entry->stride);
        } else {
          match_entry->state = NO_PRED;
          match_entry->stride= stride;
        }
        break;
      case STEADY:
        if(stride != match_entry->stride) {
          match_entry->state = INITIAL;
        } else {
          prefetch_addr = (md_addr_t)((int)addr + (int)match_entry->stride);
        }
        break;
      case NO_PRED:
        if(stride == match_entry->stride) {
          match_entry->state = TRANSIENT;
        } else {
          match_entry->stride= stride;
        }
        break;
    }
    match_entry->prev_addr = addr; 
  }
  if (prefetch_addr != 0)
    fetch_cache_blk(cp, prefetch_addr);  if (prefetch_addr != 0) {
     switch(cp->prefetch_aggr) {
      case 0:
        fetch_cache_blk(cp, prefetch_addr);
        break;
      case 1:
        prefetch_addr = (md_addr_t)((int)addr + ((int)match_entry->stride << 1) );
        fetch_cache_blk(cp, prefetch_addr);
        break;
      case 2:
        prefetch_addr = (md_addr_t)((int)addr + ((int)match_entry->stride << 2) );
        fetch_cache_blk(cp, prefetch_addr);
        break;
      case 3:
        prefetch_addr = (md_addr_t)((int)addr + ((int)match_entry->stride << 3) );
        fetch_cache_blk(cp, prefetch_addr);

        prefetch_addr += match_entry->stride;
        fetch_cache_blk(cp, prefetch_addr);
        break;
      case 4:
        prefetch_addr = (md_addr_t)((int)addr + ((int)match_entry->stride << 4) );
        fetch_cache_blk(cp, prefetch_addr);

        prefetch_addr += match_entry->stride;
        fetch_cache_blk(cp, prefetch_addr);

        prefetch_addr += match_entry->stride;
        fetch_cache_blk(cp, prefetch_addr);

        prefetch_addr += match_entry->stride;
        fetch_cache_blk(cp, prefetch_addr);

        break;
      case 5:
        prefetch_addr = (md_addr_t)((int)addr + ((int)match_entry->stride << 5) );
        fetch_cache_blk(cp, prefetch_addr);

        prefetch_addr += match_entry->stride;
        fetch_cache_blk(cp, prefetch_addr);

        prefetch_addr += match_entry->stride;
        fetch_cache_blk(cp, prefetch_addr);

        prefetch_addr += match_entry->stride;
        fetch_cache_blk(cp, prefetch_addr);
        break;
       default:
        fatal("Unsupported Prefetching aggressiveness\n");
        break;
    }
  }
  /* ECE552 Assignment 4 - END CODE */
}