⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floss_reasons.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator, developed by Nathan Binkert, * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions * from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, * and Andrew Schultz. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. */#include <cassert>#include <iostream>#include <iomanip>#include <string>#include "base/callback.hh"#include "base/cprintf.hh"#include "base/misc.hh"#include "base/statistics.hh"#include "cpu/smt.hh"#include "encumbered/cpu/full/dyn_inst.hh"#include "encumbered/cpu/full/fetch.hh"#include "encumbered/cpu/full/floss_reasons.hh"#include "encumbered/cpu/full/cpu.hh"#include "encumbered/cpu/full/issue.hh"#include "encumbered/cpu/full/thread.hh"#include "mem/mem_cmd.hh"using namespace std;#define MAYBE_INLINE#define ENABLE_COUNTER_CHECKING 0#if ENABLE_COUNTER_CHECKINGstatic void check_counters(FullCPU *, FlossState *state);#endifstatic constchar * CommitEndDesc[NUM_COMMIT_END_CAUSES] = {    "ROB_Empty",    "Commit_BW",    "StoreBuf",    "MemBarrier",    "meta: FU",    "meta: DCache"};static constchar * IssueEndDesc[NUM_ISSUE_END_CAUSES] = {    "NoInsts",    "Queue",    "IssueBW",    "TooYoung",    "IssueInorder",    "meta: Deps",    "meta: FU",    "meta: Mem"};static constchar * DisEndDesc[NUM_DIS_END_CAUSES] = {    "IREG_Full",    "FPREG_Full",    "No_Inst",    "ROB_cap",    "IQ_cap",    "BW",    "Policy",    "Serializing",    "Broken",    "meta: IQ full",    "meta: LSQ full",    "meta: ROB full"};static constchar * FetchEndDesc[NUM_FETCH_END_CAUSES] = {    "None",    "Bandwidth",    "BrLim",    "InvPC",    "BTB_Miss",    "BrRecover",    "FaultFlush",    "Sync",    "LowConf",    "Policy",    "Unknown",    "Zero_Prio",    "meta: ICache",    "meta: QFull"};//// These *_split parameters are no longer supported in the simulator// itself, but we give them dummy values here so we can leave the// related floss_reasons intact, just in case we re-implement the// parameters at some later date.//const int fetch_split = 1;const int issue_split = 1;const int decode_split = 1;const int commit_split = 1;static const char **FUDesc;////  FlossState::clear()////  This routine is called prior to the begining of each cycle//voidFlossState::clear(){    for (int t = 0; t < SMT_MAX_THREADS; ++t) {        commit_end_cause[t] = COMMIT_CAUSE_NOT_SET;        issue_end_cause[t] = ISSUE_CAUSE_NOT_SET;	//  this has to be a "policy" since this will be the "end cause"	//  for all the threads that don't get to dispatch this cycle        dispatch_end_cause = FLOSS_DIS_POLICY;	//  Can't do this, because we need the cause from last cycle...	//      machine_floss_state.fetch_end_cause[t] = FLOSS_CAUSE_NOT_SET;	for (int j = 0; j < TheISA::MaxInstSrcRegs; ++j) {	    commit_fu[t][j] = No_OpClass;	    issue_fu[t][j]  = No_OpClass;	}	// this will serve as "not set"	commit_mem_result[t] = MA_NOT_PREDICTED;	issue_mem_result[t]  = MA_NOT_PREDICTED;	fetch_mem_result[t]  = MA_NOT_PREDICTED;    }}/*-------------------------------------------------------------------*/static MAYBE_INLINE voidblame_fu(FullCPU *cpu, int thread, double total_loss, OpClass *fu_classes, 	 FlossType type){    double fu_count = 0;    for (int i = 0; i < TheISA::MaxInstSrcRegs; ++i) {	if (fu_classes[i] != No_OpClass) {	    ++fu_count;	}    }    double loss = total_loss / fu_count;    for (int i = 0; i < TheISA::MaxInstSrcRegs; ++i) {	if (fu_classes[i] != No_OpClass) {	    int fu = fu_classes[i];	    switch (type) {		case FLOSS_IQ_FU:		  cpu->floss_iqfull_fu[thread][fu] += loss;		  break;		case FLOSS_LSQ_FU:		  cpu->floss_lsqfull_fu[thread][fu] += loss;		  break;		case FLOSS_IQ_DEPS:		  cpu->floss_iqfull_deps[thread][fu] += loss;		  break;		case FLOSS_LSQ_DEPS:		  cpu->floss_lsqfull_deps[thread][fu] += loss;		  break;		case FLOSS_ROB:		  cpu->floss_robfull_fu[thread][fu] += loss;		  break;	    }	}    }}/*-------------------------------------------------------------------*/static MAYBE_INLINE voidblame_commit_stage(FullCPU *cpu, FlossState *state, int thread,		   double total_loss){    double blame_fraction[SMT_MAX_THREADS];    double loss_part;    int commit_per_thread;    int t, cause;    int blame_threads = 1;    //    //  If we are splitting bandwidth, we may blame several causes    //    if (commit_split > 1) {        commit_per_thread = cpu->commit_width / commit_split;        for (t = 0; t < cpu->number_of_threads; t++) {	    blame_fraction[t] =		(double)(commit_per_thread - cpu->n_committed[t]) /		(double)(cpu->commit_width - cpu->n_committed_total);        }	blame_threads = cpu->number_of_threads;    } else {        //  we only use the zero-th element        blame_fraction[0] = 1;    }    //  Assign loss due to thread "t" to thread "thread"    for (t=0; t<blame_threads; t++) {        loss_part = total_loss * blame_fraction[t];	cause = state->commit_end_cause[t];        switch (cause) {	  case COMMIT_FU:	    blame_fu(cpu, thread, loss_part, state->commit_fu[t], FLOSS_ROB);            break;	  case COMMIT_DMISS:	    cpu->floss_robfull_dcache[thread][state->commit_mem_result[t]] 		+= loss_part;            break;	  default:	    cpu->floss_robfull_other[thread][cause] += loss_part;            break;        }    }}/*-------------------------------------------------------------------*/static MAYBE_INLINE voidblame_issue_stage(FullCPU *cpu, FlossState *state, int thread, 		  double total_loss, bool lsq){    double blame_fraction[SMT_MAX_THREADS];    double loss_part;    int issue_per_thread;    int t, cause;    int blame_threads = 1;    //    //  If we are splitting bandwidth, we may blame several causes    //    if (issue_split > 1) {        issue_per_thread = cpu->issue_width / issue_split;        for (t = 0; t < cpu->number_of_threads; t++) {	    blame_fraction[t] =		(double)(issue_per_thread - cpu->n_issued[t]) /		(double)(cpu->issue_width - cpu->n_issued_total);	    blame_threads = cpu->number_of_threads;	}    } else {        //  we only use the zero-th element        blame_fraction[0] = 1;    }    //  Assign loss due to thread "t" to thread "thread"    for (t = 0; t < blame_threads; t++) {        loss_part = total_loss * blame_fraction[t];	cause = state->issue_end_cause[t];        switch (cause) {	  case ISSUE_DEPS:	    blame_fu(cpu, thread, loss_part, state->issue_fu[t], 		     lsq ? FLOSS_LSQ_DEPS : FLOSS_IQ_DEPS);            break;	  case ISSUE_FU:	    blame_fu(cpu, thread, loss_part, state->issue_fu[t], 		     lsq ? FLOSS_LSQ_FU : FLOSS_IQ_FU);            break;	  case ISSUE_MEM_BLOCKED:	    if (!lsq) {		cpu->floss_iqfull_dcache[thread][state->issue_mem_result[t]] 		    += loss_part;	    }	    else {		cpu->floss_lsqfull_dcache[thread][state->issue_mem_result[t]] 		    += loss_part;	    }	    break;	  default:	    if (!lsq) {		cpu->floss_iqfull_other[thread][cause] += loss_part;	    }	    else {		cpu->floss_iqfull_other[thread][cause] += loss_part;	    }            break;        }    }}/*-------------------------------------------------------------------*/static MAYBE_INLINE voidblame_dispatch_stage(FullCPU *cpu, FlossState *state, int thread, double loss) {    //    //  Having an MT front-end means that a thread can only be held    //  responsible for fetch loss is _itself_... threads do not interact    //  in the front-end (except for fetch bandwidth)    //    switch (state->dispatch_end_cause) {      case FLOSS_DIS_IQ_FULL:        //  Blame the issue stage        blame_issue_stage(cpu, state, thread, loss, true);        break;      case FLOSS_DIS_LSQ_FULL:        //  Blame the issue stage        blame_issue_stage(cpu, state, thread, loss, false);        break;      case FLOSS_DIS_ROB_FULL:        //  Blame the commit stage        blame_commit_stage(cpu, state, thread, loss);        break;      case FLOSS_DIS_CAUSE_NOT_SET:	panic("FLOSS: dispatch blamed but no cause set");	break;      default:        //  Just blame simple cause        cpu->floss_qfull_other[thread][state->dispatch_end_cause] += loss;        break;    }}/*-------------------------------------------------------------------*/voidFullCPU::flossRecord(FlossState *state, int num_fetched[]){    int thread;    double loss_to_blame = 0;                // Per-thread    int cause;    int counter;    //    //  Generally, we should only have one fetch_end_cause set...    //  However, if this is not the case, then the fetch stage is    //  indicating that we should split the loss across the threads    //  that have a reason specified.    //    //  If fetch_split is active, use "max_to_fetch", otherwise, split    //  the loss evenly between threads with a reason specified.    //    if (fetch_split < 2) {	int total_fetched = 0;	counter = 0;        for (thread = 0; thread < number_of_threads; thread++) {            if (state->fetch_end_cause[thread] != FLOSS_FETCH_CAUSE_NOT_SET)                counter++;	    total_fetched += num_fetched[thread];        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -