📄 mainsim.cc
字号:
strcat(fnsimmount, "/sim_mounts/sim_mount"); strcat(fnkernel, "/lamix/lamix"); } else { fprintf(stderr, "Can not find kernel image\n"); exit(1); } if (getcwd(fncwd, sizeof(fncwd)) == NULL) { fprintf(stderr, "Can not determine current working directory\n"); exit(1); } //------------------------------------------------------------------------- // read processor related configuration ParseConfigFile(); //------------------------------------------------------------------------- // parameter cleanup and consistency checks MAX_ACTIVE_NUMBER *= 2; MAX_ACTIVE_INSTS = MAX_ACTIVE_NUMBER / 2; if (!simulate_ilp) { // if ILP simulation is turned off MAX_ACTIVE_NUMBER = 2; // -a1 FETCHES_PER_CYCLE = 1; // -i1 DECODES_PER_CYCLE = 1; // -i1 GRADUATES_PER_CYCLE = 1; // -g1 INSTANT_ADDRESS_GENERATE = 1; // also give this the benefit of // instant address generation MAX_MEM_OPS = 1; // should show these effects ALU_UNITS = FPU_UNITS = ADDR_UNITS = 1; L1I_NUM_PORTS = 1; L1I_TAG_PORTS[0] = 1; L1D_NUM_PORTS = 1; L1D_TAG_PORTS[0] = 1; MEM_UNITS = 1; } if (MAX_ACTIVE_NUMBER > MAX_MAX_ACTIVE_NUMBER) { fprintf(stderr, "Too many active instructions; going to size %d", MAX_MAX_ACTIVE_NUMBER / 2); MAX_ACTIVE_NUMBER = MAX_MAX_ACTIVE_NUMBER; } MAX_ACTIVE_INSTS = MAX_ACTIVE_NUMBER / 2; if (GRADUATES_PER_CYCLE == 0) GRADUATES_PER_CYCLE = MAX_ACTIVE_NUMBER; else if (GRADUATES_PER_CYCLE == -1) GRADUATES_PER_CYCLE = DECODES_PER_CYCLE; if (EXCEPT_FLUSHES_PER_CYCLE == -1) EXCEPT_FLUSHES_PER_CYCLE = GRADUATES_PER_CYCLE; //------------------------------------------------------------------------- // determine stdin/stdout/stderr filenames and log/stat filenames startdir = getcwd(NULL, MAXPATHLEN); if (rsim_dirname && rsim_dirname[0] == '/') { strcpy(fnstdout, rsim_dirname); rsim_dirname = NULL; } else { strcpy(fnstdout, startdir); } if (fnstdout[strlen(fnstdout)-1] != '/') strcat(fnstdout, "/"); if (rsim_dirname) { strcat(fnstdout, rsim_dirname); if (fnstdout[strlen(fnstdout)-1] != '/') strcat(fnstdout, "/"); } strcat(fnstdout, subject); strcpy(trace_dir, fnstdout); strcpy(fnstat, fnstdout); strcpy(fnlog, fnstdout); strcpy(fnstderr, fnstdout); strcpy(fnstdin, fnstdout); strcat(fnstderr, ".stderr"); strcat(fnstdin, ".stdin"); strcat(fnstdout, ".stdout"); strcat(fnstat, ".stat"); strcat(fnlog, ".log"); if ((fd = open(fnstdin, O_RDONLY)) < 0) // check if stdin exists if (errno == ENOENT) strcpy(fnstdin, "/dev/null"); else close(fd); //------------------------------------------------------------------------- //------------------------------------------------------------------------- StartStopInit(); WatchDogInit(); DoMP(mp); //------------------------------------------------------------------------- // create a logfile for every node for (k = 0; k < ARCH_numnodes; k++) { logfile[k] = 0; statfile[k] = 0; } if (fnlog[0]) { char *fn; fn = (char*)malloc(MAX(strlen(fnlog), strlen(fnstat)) + 4); if (fn == NULL) { fprintf(stderr, "Malloc failed at %s:%i", __FILE__, __LINE__); exit(1); } for (k = 0; k < ARCH_numnodes; k++) { if (ARCH_numnodes == 1) strcpy(fn, fnlog); else if (ARCH_numnodes <= 10) sprintf(fn, "%s%i", fnlog, k); else sprintf(fn, "%s%02i", fnlog, k); logfile[k] = open(fn, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (logfile[k] < 0) fprintf(stderr, "Opening logfile %s failed: %s\n", fn, YS__strerror(errno)); if ((k < ARCH_firstnode) || (k >= ARCH_firstnode + ARCH_mynodes)) continue; if (ARCH_numnodes == 1) strcpy(fn, fnstat); else if (ARCH_numnodes <= 10) sprintf(fn, "%s%i", fnstat, k); else sprintf(fn, "%s%02i", fnstat, k); statfile[k] = open(fn, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (statfile[k] < 0) fprintf(stderr, "Opening statfile %s failed: %s\n", fn, YS__strerror(errno)); } free(fn); } //------------------------------------------------------------------------- for (k = ARCH_firstnode; k < ARCH_firstnode + ARCH_mynodes; k++) { int ac; YS__logmsg(k, "RSIM command line: "); for (ac = 0; ac < argc; ac++) YS__logmsg(k, "%s ", argv[ac]); YS__logmsg(k, "\n"); YS__logmsg(k, "\nRunning simulation on %s (%s/%s)\n", s_uname.nodename, s_uname.sysname, s_uname.machine); YS__statmsg(k, "RSIM command line: "); for (ac = 0; ac < argc; ac++) YS__statmsg(k, "%s ", argv[ac]); YS__statmsg(k, "\n"); YS__statmsg(k, "RSIM:\t Active list: %3d\n", MAX_ACTIVE_INSTS); YS__statmsg(k, "\t Speculations: %3d\n", MAX_SPEC); YS__statmsg(k, "\t Fetch rate: %3d\n", FETCHES_PER_CYCLE); YS__statmsg(k, "\t Decode rate: %3d\n", DECODES_PER_CYCLE); YS__statmsg(k, "\t Graduation rate: %3d\n", GRADUATES_PER_CYCLE); if (STALL_ON_FULL) { YS__statmsg(k, "\t ALU queue: %3d\n", MAX_ALU_OPS); YS__statmsg(k, "\t FPU queue: %3d\n", MAX_FPU_OPS); YS__statmsg(k, "\t Memory queue: %3d\n", MAX_MEM_OPS); } } fflush(NULL); //------------------------------------------------------------------------- // Set signal handler, setup various tables SetSignalHandler(); PredecodeTableSetup(); UnitArraySetup(); FuncTableSetup(); //------------------------------------------------------------------------- // Initialize the system architecture SystemInit(); AllProcs = RSIM_CALLOC(ProcState*, ARCH_numnodes * ARCH_cpus); if (!AllProcs) YS__errmsg(0, "Malloc failed in %s:%i", __FILE__, __LINE__); for (i = ARCH_cpus * ARCH_firstnode; i < ARCH_cpus * (ARCH_firstnode + ARCH_mynodes); i += ARCH_cpus) { AllProcs[i] = new ProcState(i); if (startup(fnkernel, sim_args, env, AllProcs[i]) == -1) YS__errmsg(i / ARCH_cpus, "Error loading kernel file %s", fnkernel); for (int n = 1; n < ARCH_cpus; n++) { AllProcs[i + n] = new ProcState(i + n); AllProcs[i + n]->pc = AllProcs[i]->pc; AllProcs[i + n]->npc = AllProcs[i]->npc; AllProcs[i + n]->fetch_pc = AllProcs[i]->fetch_pc; AllProcs[i + n]->kdata_segment_low = AllProcs[i]->kdata_segment_low; AllProcs[i + n]->kdata_segment_high = AllProcs[i]->kdata_segment_high; AllProcs[i + n]->ktext_segment_low = AllProcs[i]->ktext_segment_low; AllProcs[i + n]->ktext_segment_high = AllProcs[i]->ktext_segment_high; } } //------------------------------------------------------------------------- // start simulation driver EVENT *rsim_event = NewEvent("RSIM Process - all processors", RSIM_EVENT, NODELETE, 0); schedule_event(rsim_event, YS__Simtime + 0.5); // This is started at 0.5 to make sure that the smnet requests for this // time are handled _before_ the processor is handled. This is to avoid // spurious cases when an extra cycle is added in just for the processor // to see the smnet request /* start the YACSIM driver */ double walltime = time(0); DriverRun();#if defined(USESIGNAL) signal(SIGALRM, SIG_IGN);#else sigset(SIGALRM, SIG_IGN);#endif //------------------------------------------------------------------------- // simulation finished - clean up and print runtime chdir(startdir); free(startdir); walltime = time(0) - walltime; int wallhour = (int) (walltime / 3600); int wallmin = (int) (walltime - wallhour * 3600)/60; int wallsec = (int) walltime % 60; for (k = ARCH_firstnode; k < ARCH_firstnode + ARCH_mynodes; k++) { YS__statmsg(k, "\n------------------------------------------------------------------------\n\n"); YS__statmsg(k, "\nSIMULATOR STATISTICS\n\n"); YS__statmsg(k, "Simulation Host : %s (%s/%s)\n", s_uname.nodename, s_uname.sysname, s_uname.machine); YS__statmsg(k, "Processors : %i\n\n", total_processes); YS__statmsg(k, "Elapsed cycles for simulation : %.0f\n", GetSimTime()); YS__statmsg(k, "Elapsed wall time of simulation : %d:%02d:%02d\n", wallhour, wallmin, wallsec); YS__statmsg(k, "Cycles / second : %.2f\n\n", GetSimTime() / walltime); GetRusage(k); YS__statmsg(k, "\n\n"); } return;}/*=========================================================================*//* *//* The main process event; gets called every cycle performs the main *//* processor functions. The main loop calls RSIM_EVENT for each *//* processor every cycle (cycle-by-cycle processor simulation stage). *//* *//*=========================================================================*/extern "C" void RSIM_EVENT(){ int i; /* * Loop through each processor and advance simulation by a cycle */ for (i = ARCH_cpus * ARCH_firstnode; i < ARCH_cpus * (ARCH_firstnode + ARCH_mynodes); i++) { /* * Handle requests in the pipelines of the L1 cache, L1 write buffer, * and L2 cache. */ if (L1ICaches[i]->num_in_pipes) L1ICacheOutSim(i); if (L1DCaches[i]->num_in_pipes) L1DCacheOutSim(i); if (WBuffers[i]->num_in_pipes || WBuffers[i]->inqueue.size) L1DCacheWBufferSim(i); if (UBuffers[i]->num_entries) UBuffer_out_sim(i); if (L2Caches[i]->num_in_pipes) L2CacheOutSim(i); //--------------------------------------------------------------------- ProcState *proc = AllProcs[i]; if ((proc) && (!proc->halt)) { proc->curr_cycle = (long long) YS__Simtime;#ifdef COREFILE corefile = proc->corefile;#endif proc->DELAY--; if (proc->DELAY <= 0 && !proc->exit) { if (proc->in_exception != NULL) { proc->ComputeAvail(); PreExceptionHandler(proc->in_exception, proc); }#ifdef COREFILE if (proc->curr_cycle > DEBUG_TIME) fprintf(corefile, "Completion cycle %d \n", proc->curr_cycle);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -