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

📄 ms_stats.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */	/*	 *  ms_stats  -  Collect statistics on a per procedure basis during	 *		the running of the simulator.	 *	 *  Contains the functions push_stats and pop_stats, and the	 *  routine print_stats, called on program exit.	 *	 *  The PROCSTATS flag, if set, forces per procedure statistics to	 *  be kept and output at end.	 *	 *	Jim Bennett	 *	1994	 */#include <stdlib.h>#include "ms.h"#include "./ms_stats.h"#include "sim_error.h"#include "cpu_state.h"#include "mipsy.h"#include "hw_events.h"#include "statrecord.h"static	double	convert_stat (struct s_cpu_state *st, int st_index, int mode);static	double	convert_stat_sum (struct s_cpu_state *st, int st_index);static void PRINT(char *format, ...){   va_list ap;   CPUPrint("%MXS:");   va_start(ap,format);   vCPUPrint(format,ap);   va_end(ap);}/***************************************************************** * STAT RECORD ROUTINES * * All hardware events that should be tracked by statrecord go here. *****************************************************************/struct MSEventsBucket {   StatRecordFieldDesc dMXSL1Stall;   StatRecordFieldDesc dMXSL2Stall;   StatRecordFieldDesc dMXSUpgradeStall;   StatRecordFieldDesc iMXSL1Stall;   StatRecordFieldDesc iMXSL2Stall;   StatRecordFieldDesc pipelineMXSStall;} msEventBucket;#define DEF_FIELD(_field,_fl) (msEventBucket._field = StatRecordDefineField(# _field,_fl))#define STAT_RECORD(_f, _inc) \  StatRecordEntry(cpuNum, pc, vAddr, msEventBucket._f, _inc);#define STAT_RECORD_I(_f, _inc) \  StatRecordEntry(cpuNum, pc, 0, msEventBucket._f, _inc);#define STAT_RECORD_D(_f, _inc) \  StatRecordEntry(cpuNum, 0, vAddr, msEventBucket._f, _inc);void ms_events_init(void){   /* MXS-related counters */   DEF_FIELD(dMXSL1Stall, STATRECORD_INSTRUCTION|STATRECORD_DATA);   DEF_FIELD(dMXSL2Stall, STATRECORD_INSTRUCTION|STATRECORD_DATA);   DEF_FIELD(iMXSL1Stall, STATRECORD_INSTRUCTION);   DEF_FIELD(iMXSL2Stall, STATRECORD_INSTRUCTION);   DEF_FIELD(dMXSUpgradeStall, STATRECORD_INSTRUCTION|STATRECORD_DATA);   DEF_FIELD(pipelineMXSStall, STATRECORD_INSTRUCTION);}void ms_attribute_stall(int cpuNum, int vAddr, int pc, int stall, int stallType){   if (stallType & E_PIPELINE) {      STAT_RECORD_I(pipelineMXSStall,stall);      return;   }   if (stallType & E_D) {      if (stallType & E_L1) {          STAT_RECORD(dMXSL1Stall,stall);         return;      }      if (((stallType & E_L1) && (stallType & E_UPGRADE))           || ((stallType & E_L2) && (stallType & E_UPGRADE))) {         STAT_RECORD(dMXSUpgradeStall,stall);         return;      }      ASSERT(stallType & E_L2);      STAT_RECORD(dMXSL2Stall,stall);   } else {       ASSERT(vAddr==pc);      ASSERT(stallType & E_I);      if (stallType & E_L1) {         STAT_RECORD(iMXSL1Stall,stall);      } else {          ASSERT(stallType & E_L2);         STAT_RECORD(iMXSL2Stall,stall);      }   }}/*----------------------------------------------------------------------*//*									*//*	ms_exec never returns, but exits when the app calls exit.	*//*	But just before exiting, the following routine gets called	*//*	to print out the collected statistics.				*//*									*//*----------------------------------------------------------------------*/void print_stats (struct s_cpu_state *st)	{	}	/*	 *  convert_stat  -  Convert statistic to double precision	 *		     floating point number.	 */static double convert_stat (struct s_cpu_state *st, int st_index, int mode)	{	double	t;	t = (double) (st->stats[mode][st_index]);	return (t);	}	/*	 *  convert_stat_sum  -  Convert statistic to double precision	 *		         floating point number.	 */static double convert_stat_sum (struct s_cpu_state *st, int st_index)	{         return (convert_stat(st,st_index,0) + 		 convert_stat(st,st_index,1) +		 convert_stat(st,st_index,2) + 		 convert_stat(st,st_index,3));        	}void dump_stats (struct s_cpu_state *st){	int	i, mode;    if ((st->work_ticks == 0) && (st->work_cycle == 0)) {	    /* Must not of run yet. */            return;    }        for (mode = 0; mode < NUM_MODES; mode++) {             {		CPUState *P = (CPUState *) (st->mipsyPtr); 	        PRINT( "DUMPSTATS: CPU %d MODE %d @ %lld %9d%0.5d\n", P->myNum,mode,		         (uint64)MipsyReadTime(P->myNum), st->work_ticks, st->work_cycle);	     }/* Then output gathered statistics		*/	     for (i = 0; i < ST_NTYPES; i++) {		 if (sh_stat_names[i][0] == 0) continue;#define PRINT_IF_NOT_ZERO(_format, _name, _value) \             if ((_value) != 0) PRINT(_format, _name, (double)(_value))		 PRINT_IF_NOT_ZERO( "%s: %.0f\n", sh_stat_names[i],                                    convert_stat(st,i, mode));	     }#undef PRINT_IF_NOT_ZERO#define PRINT_IF_NOT_ZERO(_format, _index, _value) \             if ((_value) != 0) PRINT(_format, _index, (double)(_value))             PRINT_IF_NOT_ZERO("SAMPLE: %d %.0f\n",mode,st->sample_stats[mode].samples);             for (i = 0; i < (sizeof(st->sample_stats[mode].nthreads_hist) /                               sizeof(st->sample_stats[mode].nthreads_hist[0])); i++) {                                PRINT_IF_NOT_ZERO("NTHREADS_HIST: %d %.0f\n",i,st->sample_stats[mode].nthreads_hist[i]);             }             for (i = 0; i < (sizeof(st->sample_stats[mode].reg_hist) /                               sizeof(st->sample_stats[mode].reg_hist[0])); i++) {                                PRINT_IF_NOT_ZERO("REGS_HIST: %d %.0f\n",i,st->sample_stats[mode].reg_hist[i]);             }             for (i = 0; i < (sizeof(st->sample_stats[mode].iwin_hist) /                               sizeof(st->sample_stats[mode].iwin_hist[0])); i++) {                                PRINT_IF_NOT_ZERO("IWIN_INST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].iwin_hist[i].inst);                PRINT_IF_NOT_ZERO("IWIN_SPECINST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].iwin_hist[i].specInst);                PRINT_IF_NOT_ZERO("IWIN_LDST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].iwin_hist[i].ldstInst);                PRINT_IF_NOT_ZERO("IWIN_LDSTDEP_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].iwin_hist[i].ldstdepInst);                PRINT_IF_NOT_ZERO("IWIN_REGDEP_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].iwin_hist[i].regdepInst);                PRINT_IF_NOT_ZERO("IWIN_SQUASH_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].iwin_hist[i].squashInst);             }             for (i = 0; i < (sizeof(st->sample_stats[mode].ldst_hist) /                               sizeof(st->sample_stats[mode].ldst_hist[0])); i++) {                                PRINT_IF_NOT_ZERO("LDST_INST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].ldst_hist[i].inst);                PRINT_IF_NOT_ZERO("LDST_DONE_INST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].ldst_hist[i].doneInst);                PRINT_IF_NOT_ZERO("LDST_PEND_INST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].ldst_hist[i].pendInst);                PRINT_IF_NOT_ZERO("LDST_CONFLICT_INST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].ldst_hist[i].conflictInst);                PRINT_IF_NOT_ZERO("LDST_FAILED_INST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].ldst_hist[i].failedInst);                PRINT_IF_NOT_ZERO("LDST_STALL_INST_HIST: %d %.0f\n",i,                                  st->sample_stats[mode].ldst_hist[i].stallInst);             }                                  	}}void MxsPrintStatus(struct s_cpu_state *st) {  return;#ifdef BANREMOVE  double grad_insts, grad_squashed, cond_br_correct, cond_br_incorrect,            ind_br_correct, ind_br_incorrect;    double igrad_insts, igrad_squashed, icond_br_correct, icond_br_incorrect,            iind_br_correct, iind_br_incorrect;    CPUState *P = (CPUState *) (st->mipsyPtr);    static struct { 	double grad_insts, grad_squashed, cond_br_correct, cond_br_incorrect,            ind_br_correct, ind_br_incorrect;           } old[MIPSY_MAX_CPUS];     if ((st->work_ticks == 0) && (st->work_cycle == 0)) {	    /* Must not of run yet. */            return;    }    cond_br_correct = convert_stat_sum (st, ST_CORRECT_FALLTHRU) + 		      convert_stat_sum (st, ST_CORRECT_W_FALLTHRU) + 		      convert_stat_sum (st, ST_CORRECT_W_TAKEN) +		      convert_stat_sum (st, ST_CORRECT_TAKEN);    cond_br_incorrect = convert_stat_sum (st, ST_INCORRECT_FALLTHRU) + 		      convert_stat_sum (st, ST_INCORRECT_W_FALLTHRU) + 		      convert_stat_sum (st, ST_INCORRECT_W_TAKEN) +		      convert_stat_sum (st, ST_INCORRECT_TAKEN);    ind_br_correct = convert_stat_sum (st, ST_CORRECT_IND_BR);    ind_br_incorrect = convert_stat_sum (st, ST_INCORRECT_IND_BR);    grad_insts = (double) P->numInstructions;    grad_squashed = convert_stat_sum (st, ST_GRAD_SQUASHED);    icond_br_correct = cond_br_correct - old[P->myNum].cond_br_correct;    icond_br_incorrect = cond_br_incorrect - old[P->myNum].cond_br_incorrect;    iind_br_correct = ind_br_correct - old[P->myNum].ind_br_correct;    iind_br_incorrect = ind_br_incorrect - old[P->myNum].ind_br_incorrect;    igrad_insts = grad_insts - old[P->myNum].grad_insts;    igrad_squashed = grad_squashed - old[P->myNum].grad_squashed;    PRINT ("CPU%d BR (%3.1f%%) JR (%3.1f%%) Squash (%3.1f%%)\n",P->myNum,	   100.0*icond_br_correct/(icond_br_correct + icond_br_incorrect + .0000001),	   100.0*iind_br_correct/(iind_br_correct + iind_br_incorrect + .0000001),	   100.0*igrad_squashed/(igrad_squashed + igrad_insts + .0000001));   old[P->myNum].grad_insts = grad_insts;   old[P->myNum].grad_squashed = grad_squashed;   old[P->myNum].cond_br_correct = cond_br_correct;   old[P->myNum].cond_br_incorrect = cond_br_incorrect;   old[P->myNum].ind_br_correct = ind_br_correct;   old[P->myNum].ind_br_incorrect = ind_br_incorrect;#endif}void MxsSampleStats(struct s_cpu_state *st, int mode) {    int inum, r;    struct s_ldst_buffer *entry;    int  instInWindow , specInstInWindow , ldstInstInWindow ,        ldstdepInstInWindow , regdepInstInWindow , squashInstInWindow;    int  ldstBufferInst, ldstDoneInst , ldstConflictInst , ldstFailedInst,         ldstStallInst,  ldstPendInst;    int regBusyCount;    st->sample_stats[mode].samples++;    st->sample_stats[mode].nthreads_hist[st->nthreads]++;    regBusyCount = 0;     for (r = 0; r < MAX_PREG/2; r++) {        if (st->reg_rstat[r].reg_status & REG_BUSY)           regBusyCount++;     }     st->sample_stats[mode].reg_hist[regBusyCount]++;     instInWindow = specInstInWindow =  ldstInstInWindow =        ldstdepInstInWindow = regdepInstInWindow = squashInstInWindow = 0;     inum = st->iwin_headgrad;      while (inum >= 0) {         int flags = st->iwin_flags[inum];         instInWindow++;         if (flags & IWIN_SPEC)             specInstInWindow++;         if (flags & IWIN_LDST)             ldstInstInWindow++;         if (flags & IWIN_LDST_DEP)             ldstdepInstInWindow++;         if (flags & (IWIN_DEP2|IWIN_DEP3))             regdepInstInWindow++;         if (flags & IWIN_SQUASH)             squashInstInWindow++;         inum = st->iwin_grad[inum];     }     st->sample_stats[mode].iwin_hist[instInWindow].inst++;     st->sample_stats[mode].iwin_hist[specInstInWindow].specInst++;     st->sample_stats[mode].iwin_hist[ldstInstInWindow].ldstInst++;     st->sample_stats[mode].iwin_hist[ldstdepInstInWindow].ldstdepInst++;     st->sample_stats[mode].iwin_hist[regdepInstInWindow].regdepInst++;     st->sample_stats[mode].iwin_hist[squashInstInWindow].squashInst++;     ldstBufferInst = ldstDoneInst = ldstConflictInst = ldstFailedInst =         ldstStallInst = ldstPendInst = 0;     for (entry = st->ldst_head; entry; entry = entry->next) {        int status = entry->ls->status;        ldstBufferInst++;        if (status & LS_ST_DONE) {           ldstDoneInst++;           continue;        }        if (status & LS_ST_PEND)            ldstPendInst++;        if (status & LS_ST_CONFLICT)            ldstConflictInst++;        if (status & LS_ST_FAILED)            ldstFailedInst++;        if (status & LS_ST_STALL)            ldstStallInst++;     }     st->sample_stats[mode].ldst_hist[ldstBufferInst].inst++;     st->sample_stats[mode].ldst_hist[ldstDoneInst].doneInst++;     st->sample_stats[mode].ldst_hist[ldstPendInst].pendInst++;     st->sample_stats[mode].ldst_hist[ldstConflictInst].conflictInst++;     st->sample_stats[mode].ldst_hist[ldstFailedInst].failedInst++;     st->sample_stats[mode].ldst_hist[ldstStallInst].stallInst++;}

⌨️ 快捷键说明

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