📄 stats.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. * *//***************************************************************** * stats.c * Statistics support for mipsy. More specific statistics are kept * with the caches and memory systems right now. I'll abstract them * later. * * $Author: bosch $ * $Date: 1998/02/10 00:32:02 $ *****************************************************************/#include <sys/time.h>#include <stdio.h>#include <strings.h>#include "mipsy.h"#include "cpu_stats.h"#include "simstats.h"#include "simstats.h"#include "cpu_state.h"#include "cpu.h"#include "sim_error.h"#include "eventcallback.h"#include "cpu_interface.h"#include "hw_events.h"#include "machine_params.h"#include "memref.h"#ifdef MIPSY_MXS#include "ms.h"#endif#include "simutil.h"#ifdef SOLO#include "solo.h"#include "tcl_init.h"#endif#include "addr_layout.h"/* Local Functions */static void EnablePeriodicStats(int cpuNum, SimTime interval);static void PeriodicStats(SimTime cycleCount);/***************************************************************** * MipsyInitStats * *****************************************************************/voidMipsyInitStats(void){ MemRefInit(); InitCPUStats(); EnablePeriodicStats(0, SAMPLE_PC_INTERVAL);}/***************************************************************** * MipsyResetStats * *****************************************************************/ voidMipsyResetStats(void){ unsigned i; ResetCPUStats(); for (i=0; i < TOTAL_CPUS; i++) { MemRefResetStats(i); }#ifdef SOLO Tcl_Eval(TCLInterp, "annotation exec solo resetStats");#endif}/***************************************************************** * MipsyStatsCallback: * * This is a heavily used callback. Right now I check almost every * periodic event here and process it if needed. It also prints out * a whole mess of statistics at regular intervals and then reinstalls * itelf everytime. This event is called every SAMPLE_PC_INTERVAL. * * We do all kinds of things here that aren't directly related to * stats, including checking for interrupts and for exit conditions. * Additionally, every STAT_INTERVAL cycles we call out to print the * periodic statistics. *****************************************************************/static struct StatsHdr { EventCallbackHdr hdr; SimTime statsInterval; int periodicStats; int intervalsLeft;} statsEvent[MIPSY_MAX_CPUS];static void MipsyStatsCallback(int cpuNum, EventCallbackHdr *hdr, void *arg){ int cpu; if (simosCPUType != MIPSY) { return; } for (cpu = 0; cpu < TOTAL_CPUS; cpu++) { CPUState *P = &(PE[cpu]); if (P->cpuStatus == cpu_halted) { continue; }#ifndef SOLO if (!IS_KSEG1(P->PC) && P->PC) { CYCLE_SAMPLE_EVENT(MipsyReadTime(cpu), cpu, P->PC); } else { /* we sample all backdoor PC to the same address. */ CYCLE_SAMPLE_EVENT(MipsyReadTime(cpu),cpu,K1BASE); }#else CYCLE_SAMPLE_EVENT(MipsyReadTime(cpu), cpu, P->PC);#endif#ifdef MIPSY_MXS if (PE[cpu].inMXS) MxsSampleStats(PE[cpu].st, CURRENT_MODE(&PE[cpu]));#endif } --statsEvent[cpuNum].intervalsLeft; if (statsEvent[cpuNum].intervalsLeft <= 0) { statsEvent[cpuNum].intervalsLeft = statsEvent[cpuNum].periodicStats; PERIODIC_EVENT; PeriodicStats((SimTime)MipsyReadTime(cpuNum)); } /* Things to do each STAT_INTERVAL */ EventDoCallback(cpuNum, MipsyStatsCallback, (EventCallbackHdr *)&statsEvent[cpuNum], 0, statsEvent[cpuNum].statsInterval);}/***************************************************************** * EnablePeriodicStats * * Installs the first statistics callback. When the callback runs, it * will reinsert itself into the callback queue. *****************************************************************/static void EnablePeriodicStats(int cpuNum, SimTime statInterval){ statsEvent[cpuNum].statsInterval = statInterval; statsEvent[cpuNum].periodicStats = STAT_INTERVAL / statInterval; statsEvent[cpuNum].intervalsLeft = statsEvent[cpuNum].periodicStats; EventDoCallback(0, MipsyStatsCallback, (EventCallbackHdr *)&statsEvent[cpuNum], 0, statInterval);}/***************************************************************** * PeriodicStats * * Current means of printing out periodic statistics. This is * called at the end of each "STAT_INTERVAL" and when it is time to * exit mipsy. Every "DETAILED_STAT_INTERVAL" some extra stuff will be * printed out. *****************************************************************/static SimCounter oldTotalIcnt;static SimTime oldCycleCnt;static long secondsRun;static voidPeriodicStats(SimTime cycleCount){ int cpuNum; PrintPeriodicCPUStats(); for (cpuNum = 0; cpuNum < TOTAL_CPUS; cpuNum++) { /* The memory subsystem should do any sampling and printing in this procedure. */ if (!SKIP_CACHES(P)) { MemRefPeriodicStats(cpuNum); }#ifdef MIPSY_MXS { CPUState *P = &(PE[cpuNum]); MxsPrintStatus(P->st); dump_stats(P->st); }#endif }}/***************************************************************** * MipsyDumpAllStats * * Complete dumping of stats. * This is typically called at the end of execution. *****************************************************************/voidMipsyDumpAllStats(void) { int cpuNum; CPUPrint("*******************DUMPING MIPSY STATS******************* \n"); PrintAllCPUStats(); CPUPrint("************\n"); CPUPrint("Cache Stats\n"); CPUPrint("************\n"); for (cpuNum=0; cpuNum<TOTAL_CPUS; cpuNum++) { CPUPrint("C%d Stall Time: %d\n", cpuNum, STATS_VALUE(cpuNum, stallTime));#ifdef MIPSY_MXS dump_stats(PE[cpuNum].st);#endif if (!SKIP_CACHES(&PE[cpuNum])) { MemRefDumpStats(cpuNum); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -