📄 mainsim.cc
字号:
/* Completion stage of the pipeline */ CompleteMemQueue(proc); CompleteQueues(proc); if (proc->in_exception == NULL && !proc->exit) /* Main processor pipeline */ maindecode(proc); if (proc->exit) { aliveprocs--; DoExit(); if (aliveprocs == 0) /* otherwise, just keep running, since caches might still need to service INVL requests, etc. */ { EXIT = 1; return; } } if (proc->DELAY <= 0) { // if (proc->ReadyQueue_count > 0) IssueQueues(proc); /* Issue to queues */#ifdef STORE_ORDERING if (proc->MemQueue.NumItems() && proc->UnitsFree[uMEM]) IssueMem(proc);#else if ((proc->LoadQueue.NumItems() || proc->StoreQueue.NumItems()) && proc->UnitsFree[uMEM]) IssueMem(proc);#endif proc->DELAY = 1; }#ifndef NOSTAT StatrecUpdate(proc->SpecStats, proc->branchq.NumItems(), 1); for (int ctrfu = 0; ctrfu < numUTYPES; ctrfu++) StatrecUpdate(proc->FUUsage[ctrfu], proc->MaxUnits[ctrfu]-proc->UnitsFree[ctrfu], 1);#ifndef STORE_ORDERING StatrecUpdate(proc->VSB, proc->StoresToMem, 1); StatrecUpdate(proc->LoadQueueSize, proc->LoadQueue.NumItems(), 1);#else StatrecUpdate(proc->MemQueueSize, proc->MemQueue.NumItems(), 1);#endif StatrecUpdate(proc->FetchQueueStats, proc->fetch_queue->NumItems(), 1); StatrecUpdate(proc->ActiveListStats, proc->active_list.NumElements(), 1);#endif } } /* * Handle requests coming into L1 cache and L2 cache */ if (!(L1ICaches[i]->inq_empty)) L1ICacheInSim(i); if (!(L1DCaches[i]->inq_empty)) L1DCacheInSim(i); if (!(L2Caches[i]->inq_empty)) L2CacheInSim(i); } //------------------------------------------------------------------------- // Schedule the main processorloop for next cycle schedule_event(YS__ActEvnt, YS__Simtime + 1.0);}/***********************************************************************//* Watchdog - detects stalled CPUs and suspends simulation. *//***********************************************************************/#define WATCHDOG_PERIOD 10000.0 * 1000000.0 / CPU_CLK_PERIODlong long *WatchDogCounts;extern "C" void WatchDog(){ int n; EVENT *ev = (EVENT*)EventGetArg(NULL); if (EXIT) return; for (n = ARCH_cpus * ARCH_firstnode; n < ARCH_cpus * (ARCH_firstnode + ARCH_mynodes); n++) { if (WatchDogCounts[n] == AllProcs[n]->graduates) { YS__logmsg(n / ARCH_cpus, "Watchdog: CPU %i node %i appears stalled\n", n % ARCH_cpus, n / ARCH_cpus); YS__logmsg(n / ARCH_cpus, "Suspending process\n"); YS__logmsg(n / ARCH_cpus, "Resume simulation by sending SIGCONT (%i) to process %i\n", SIGCONT, getpid()); kill(getpid(), SIGSTOP); } WatchDogCounts[n] = AllProcs[n]->graduates; } schedule_event(ev, YS__Simtime + WATCHDOG_PERIOD);}int WatchDogInit(){ EVENT *ev; int n; WatchDogCounts = (long long*)malloc(sizeof(long long) * ARCH_numnodes * ARCH_cpus); if (WatchDogCounts == NULL) YS__errmsg(0, "Failed to allocated watchdog counts\n"); for (n = 0; n < ARCH_numnodes * ARCH_cpus; n++) WatchDogCounts[n] = 0; ev = NewEvent("Processor Watchdog", WatchDog, NODELETE, 0); EventSetArg(ev, ev, sizeof(ev)); schedule_event(ev, YS__Simtime + WATCHDOG_PERIOD); return(0);}/***********************************************************************//* Handle start/stop event: scheduled at the earliest time graduation *//* count may reach desired start or stop count. Find maximum *//* graduation count among all processors. If start/reset count is *//* given, check if reached and then reset all statistics, otherwise *//* reschedule for next earliest time. If stop count is given, check *//* if reached, then dump statistics and interrupt all processors, *//* otherwise reschedule. *//***********************************************************************/extern "C" void StartStopHandle(){ int n; long long max_inst = 0; long long del; EVENT *ev = (EVENT*)EventGetArg(NULL); // simulation exiting, don't bother if (EXIT) return; // find highest graduated instruction count for (n = 0; n < ARCH_numnodes * ARCH_cpus; n++) if (AllProcs[n]->graduates > max_inst) max_inst = AllProcs[n]->graduates; // still waiting to reset statistics if (reset_instruction != 0) { // reset instruction reached: reset statistics if (max_inst >= reset_instruction) { for (n = ARCH_firstnode; n < ARCH_firstnode + ARCH_mynodes; n++) { YS__logmsg(n, "Reset instruction %lld reached - reset statistics\n", reset_instruction); StatClear(n); } reset_instruction = 0; max_inst = 0; } // start instruction not reached: reschedule else { del = (reset_instruction - max_inst) / GRADUATES_PER_CYCLE; if (del <= 0) del = 1; schedule_event(ev, YS__Simtime + del);#ifdef DEBUG YS__logmsg(0, "%.0f: Reset instr. not reached (%lld > %lld) - reschedule for %.0f\n", YS__Simtime, reset_instruction, max_inst, YS__Simtime + del);#endif } } // waiting to reach stop instruction if ((reset_instruction == 0) && (stop_instruction != 0)) { if (max_inst >= stop_instruction) { for (n = ARCH_firstnode; n < ARCH_firstnode + ARCH_mynodes; n++) { YS__logmsg(n, "Stop instruction %lld reached - write statistics\n", stop_instruction); StatReport(n); } for (n = ARCH_cpus * ARCH_firstnode; n < ARCH_cpus * (ARCH_firstnode + ARCH_mynodes); n += ARCH_cpus) ExternalInterrupt(n, IPL_PFAIL); stop_instruction = 0; } else { del = (stop_instruction - max_inst) / GRADUATES_PER_CYCLE; if (del <= 0) del = 1; schedule_event(ev, YS__Simtime + del);#ifdef DEBUG YS__logmsg(0, "%.0f: Stop instr. not reached (%lld > %lld) - reschedule for %.0f\n", YS__Simtime, stop_instruction, max_inst, YS__Simtime + del);#endif } }}/***********************************************************************//* Initialize 'start/stop' feature. If start and/or stop instruction *//* is specified, create event and schedule accordingly. *//* Schedule time is estimated by assuming maximum graduation rate per *//* cycle and remaining instructions to go. When scheduled, handler *//* checks actual graduation count and reschedules if needed. *//***********************************************************************/int StartStopInit(){ EVENT *ev; // skip if neither start nor stop is specified if ((reset_instruction == 0) && (stop_instruction == 0)) return(0); // check that stop is past start, unless stop is not specified if ((reset_instruction >= stop_instruction) && (stop_instruction != 0)) { fprintf(stderr, "Reset instruction count (%lld) greater than stop instruction count (%lld)\n", reset_instruction, stop_instruction); exit(1); } ev = NewEvent("Start/Stop Statistics & Simulation", StartStopHandle, NODELETE, 0); EventSetArg(ev, ev, sizeof(ev)); if (reset_instruction > 0) { schedule_event(ev, reset_instruction / GRADUATES_PER_CYCLE); } else { schedule_event(ev, stop_instruction / GRADUATES_PER_CYCLE); }}/***********************************************************************/void GetRusage(int node){ unsigned int user_sec, user_min, user_hour; unsigned int sys_sec, sys_min, sys_hour; unsigned int total_sec, total_min, total_hour; int width, wu, ws, n; struct rusage Rusage; getrusage(RUSAGE_SELF, &Rusage); user_sec = Rusage.ru_utime.tv_sec; sys_sec = Rusage.ru_stime.tv_sec; total_hour = (user_sec + sys_sec) / 3600; total_min = ((user_sec + sys_sec) % 3600) / 60; total_sec = (user_sec + sys_sec) % 60; user_hour = user_sec / 3600; user_min = (user_sec % 3600) / 60; user_sec = user_sec % 60; sys_hour = sys_sec / 3600; sys_min = (sys_sec % 3600) / 60; sys_sec = sys_sec % 60; width = total_hour > 0 ? (int)log10(double(total_hour)) : 0; ws = sys_hour > 0 ? (int)log10(double(sys_hour)) : 0; wu = user_hour > 0 ? (int)log10(double(user_hour)) : 0; YS__statmsg(node, "Resource Usage\n"); YS__statmsg(node, " total cpu time : %d:%02d:%02d\n", total_hour, total_min, total_sec); YS__statmsg(node, " system time : "); for (n = 0; n < width - ws; n++) YS__statmsg(node, " "); YS__statmsg(node, "%d:%02d:%02d\n", sys_hour, sys_min, sys_sec); YS__statmsg(node, " user time : "); for (n = 0; n < width - wu; n++) YS__statmsg(node, " "); YS__statmsg(node, "%d:%02d:%02d\n", user_hour, user_min, user_sec); YS__statmsg(node, " major page faults : %d\n", Rusage.ru_majflt); YS__statmsg(node, " minor page faults : %d\n", Rusage.ru_minflt); YS__statmsg(node, " voluntary context switches : %d\n", Rusage.ru_nvcsw); YS__statmsg(node, " involuntary context switches : %d\n", Rusage.ru_nivcsw);}/***********************************************************************/void PrintHelpInformation(char *progname){ printf("usage: %s [simulator-options] -F [application-options]\n\n", progname); puts("simulator options are:"); puts("\t-d - turn on bus trace"); puts("\t-e eaddr - Send an email notification to the specified"); puts("\t address upon completion of this simulation"); puts("\t-m cpus - parallel simulation on up to M processors"); puts("\t-n - lower simulator priority (nice)"); puts("\t-r icount - reset statistics when icount instructions are graduated"); puts("\t-s icount - write statistics and abort simulation when icount instructions are graduated"); puts("\t-t time - print debugging output after time T"); puts("\t-z file - Configuration file (default: rsim_params)"); puts("\t-D dir - Directory for output file"); puts("\t-S subj - Subject to use in output filenames"); puts("\t-X - Static scheduling (partially supported)"); puts("\n[Application options] depend on specific applications"); puts("For more information, please refer to the RSIM manual for a"); puts("detailed description of the RSIM command line options.");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -