/* print all simulator stats */ void sim_print_stats(FILE *fd) /* output stream */ { #if 0 /* not portable... :-( */ extern char etext, *sbrk(int); #endif if (!running) return; /* get stats time */ sim_end_time = time((time_t *)NULL); sim_elapsed_time = MAX(sim_end_time - sim_start_time, 1); #if 0 /* not portable... :-( */ /* compute simulator memory usage */ sim_mem_usage = (sbrk(0) - &etext) / 1024; #endif /* print simulation stats */ fprintf(fd, "\nsim: ** simulation statistics **\n"); stat_print_stats(sim_sdb, fd); sim_aux_stats(fd); fprintf(fd, "\n"); //Yuanwen Added here struct stat_stat_t * stat_max_power = stat_find_stat(sim_sdb, "max_cycle_power_cc3"); FILE *f=fopen("MaxPower.txt", "w"); fprintf(f, "%g", *stat_max_power->variant.for_double.var); //Yuanwen Added /* instantiate a new evaluator to avoid recursion problems */ struct eval_state_t *es = eval_new(stat_eval_ident, sim_sdb); //stat_eval_ident() is a function char *endp; struct stat_stat_t * stat_avg_total_power = stat_find_stat(sim_sdb, "avg_total_power_cycle_cc3"); struct eval_value_t val = eval_expr(es, stat_avg_total_power->variant.for_formula.formula, &endp); // if (eval_error != ERR_NOERR || *endp != '\0') // fprintf(fd, "<error: %s>", eval_err_str[eval_error]); // else // myfprintf(fd, stat->format, eval_as_double(val)); // fprintf(fd, " # %s", stat->desc); fprintf(f, ",%g", eval_as_double(val)); struct stat_stat_t * stat_1 = stat_find_stat(sim_sdb, "avg_alu_power_cc3"); struct eval_value_t val_1 = eval_expr(es, stat_1->variant.for_formula.formula, &endp); fprintf(f, ",%g", eval_as_double(val_1)); struct stat_stat_t * stat_2 = stat_find_stat(sim_sdb, "avg_lsq_power_cc3"); struct eval_value_t val_2 = eval_expr(es, stat_2->variant.for_formula.formula, &endp); fprintf(f, ",%g", eval_as_double(val_2)); /* done with the evaluator */ eval_delete(es); fclose(f); }
void translate_uncore_stats(struct stat_sdb_t* sdb, root_system* stats) { struct stat_stat_t* curr_stat = NULL; if (uncore->LLC) { if (!private_l2) { curr_stat = stat_find_stat(sdb, "LLC.load_lookups"); stats->L2[0].read_accesses = curr_stat->variant.for_sqword.end_val; curr_stat = stat_find_stat(sdb, "LLC.load_misses"); stats->L2[0].read_misses = curr_stat->variant.for_sqword.end_val; curr_stat = stat_find_stat(sdb, "LLC.store_lookups"); stats->L2[0].write_accesses = curr_stat->variant.for_sqword.end_val; curr_stat = stat_find_stat(sdb, "LLC.store_misses"); stats->L2[0].write_misses = curr_stat->variant.for_sqword.end_val; } else { curr_stat = stat_find_stat(sdb, "LLC.load_lookups"); stats->L3[0].read_accesses = curr_stat->variant.for_sqword.end_val; curr_stat = stat_find_stat(sdb, "LLC.load_misses"); stats->L3[0].read_misses = curr_stat->variant.for_sqword.end_val; curr_stat = stat_find_stat(sdb, "LLC.store_lookups"); stats->L3[0].write_accesses = curr_stat->variant.for_sqword.end_val; curr_stat = stat_find_stat(sdb, "LLC.store_misses"); stats->L3[0].write_misses = curr_stat->variant.for_sqword.end_val; } } curr_stat = stat_find_stat(sdb, "uncore.sim_cycle"); stats->total_cycles = curr_stat->variant.for_sqword.end_val; }
/* register simulator-specific statistics */ void sim_reg_stats(struct stat_sdb_t *sdb) /* stats database */ { int i; /* register baseline stats */ stat_reg_counter(sdb, "sim_num_insn", "total number of instructions executed", &sim_num_insn, sim_num_insn, NULL); stat_reg_counter(sdb, "sim_num_refs", "total number of loads and stores executed", &sim_num_refs, 0, NULL); stat_reg_int(sdb, "sim_elapsed_time", "total simulation time in seconds", &sim_elapsed_time, 0, NULL); stat_reg_formula(sdb, "sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / sim_elapsed_time", NULL); /* register cache stats */ if (cache_il1 && (cache_il1 != cache_dl1 && cache_il1 != cache_dl2)) cache_reg_stats(cache_il1, sdb); if (cache_il2 && (cache_il2 != cache_dl1 && cache_il2 != cache_dl2)) cache_reg_stats(cache_il2, sdb); if (cache_dl1) cache_reg_stats(cache_dl1, sdb); if (cache_dl2) cache_reg_stats(cache_dl2, sdb); if (itlb) cache_reg_stats(itlb, sdb); if (dtlb) cache_reg_stats(dtlb, sdb); for (i=0; i<pcstat_nelt; i++) { char buf[512], buf1[512]; struct stat_stat_t *stat; /* track the named statistical variable by text address */ /* find it... */ stat = stat_find_stat(sdb, pcstat_vars[i]); if (!stat) fatal("cannot locate any statistic named `%s'", pcstat_vars[i]); /* stat must be an integral type */ if (stat->sc != sc_int && stat->sc != sc_uint && stat->sc != sc_counter) fatal("`-pcstat' statistical variable `%s' is not an integral type", stat->name); /* register this stat */ pcstat_stats[i] = stat; pcstat_lastvals[i] = STATVAL(stat); /* declare the sparce text distribution */ sprintf(buf, "%s_by_pc", stat->name); sprintf(buf1, "%s (by text address)", stat->desc); pcstat_sdists[i] = stat_reg_sdist(sdb, buf, buf1, /* initial value */0, /* print fmt */(PF_COUNT|PF_PDF), /* format */"0x%p %u %.2f", /* print fn */NULL); } ld_reg_stats(sdb); mem_reg_stats(mem, sdb); }
/* register simulator-specific statistics */ void sim_reg_stats(struct stat_sdb_t *sdb) { int i; stat_reg_counter(sdb, "sim_num_insn", "total number of instructions executed", &sim_num_insn, sim_num_insn, NULL); stat_reg_counter(sdb, "sim_num_refs", "total number of loads and stores executed", &sim_num_refs, 0, NULL); stat_reg_int(sdb, "sim_elapsed_time", "total simulation time in seconds", &sim_elapsed_time, 0, NULL); stat_reg_formula(sdb, "sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / sim_elapsed_time", NULL); if (prof_ic) { /* instruction class profile */ ic_prof = stat_reg_dist(sdb, "sim_inst_class_prof", "instruction class profile", /* initial value */0, /* array size */ic_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */inst_class_str, /* print fn */NULL); } if (prof_inst) { int i; char buf[512]; /* conjure up appropriate instruction description strings */ for (i=0; i < /* skip NA */OP_MAX-1; i++) { sprintf(buf, "%-8s %-6s", md_op2name[i+1], md_op2format[i+1]); inst_str[i] = mystrdup(buf); } /* instruction profile */ inst_prof = stat_reg_dist(sdb, "sim_inst_prof", "instruction profile", /* initial value */0, /* array size */ /* skip NA */OP_MAX-1, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */inst_str, /* print fn */NULL); } if (prof_bc) { /* instruction branch profile */ bc_prof = stat_reg_dist(sdb, "sim_branch_prof", "branch instruction profile", /* initial value */0, /* array size */bc_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */branch_class_str, /* print fn */NULL); } if (prof_am) { /* instruction branch profile */ am_prof = stat_reg_dist(sdb, "sim_addr_mode_prof", "addressing mode profile", /* initial value */0, /* array size */md_amode_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */md_amode_str, /* print fn */NULL); } if (prof_seg) { /* instruction branch profile */ seg_prof = stat_reg_dist(sdb, "sim_addr_seg_prof", "load/store address segment profile", /* initial value */0, /* array size */seg_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */addr_seg_str, /* print fn */NULL); } if (prof_tsyms && sym_ntextsyms != 0) { int i; /* load program symbols */ sym_loadsyms(ld_prog_fname, load_locals); /* conjure up appropriate instruction description strings */ tsym_names = (char **)calloc(sym_ntextsyms, sizeof(char *)); for (i=0; i < sym_ntextsyms; i++) tsym_names[i] = sym_textsyms[i]->name; /* text symbol profile */ tsym_prof = stat_reg_dist(sdb, "sim_text_sym_prof", "text symbol profile", /* initial value */0, /* array size */sym_ntextsyms, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */tsym_names, /* print fn */NULL); } if (prof_dsyms && sym_ndatasyms != 0) { int i; /* load program symbols */ sym_loadsyms(ld_prog_fname, load_locals); /* conjure up appropriate instruction description strings */ dsym_names = (char **)calloc(sym_ndatasyms, sizeof(char *)); for (i=0; i < sym_ndatasyms; i++) dsym_names[i] = sym_datasyms[i]->name; /* data symbol profile */ dsym_prof = stat_reg_dist(sdb, "sim_data_sym_prof", "data symbol profile", /* initial value */0, /* array size */sym_ndatasyms, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */dsym_names, /* print fn */NULL); } if (prof_taddr) { /* text address profile (sparse profile), NOTE: a dense print format is used, its more difficult to read, but the profiles are *much* smaller, I've assumed that the profiles are read by programs, at least for your sake I hope this is the case!! */ taddr_prof = stat_reg_sdist(sdb, "sim_text_addr_prof", "text address profile", /* initial value */0, /* print format */(PF_COUNT|PF_PDF), /* format */"0x%p %u %.2f", /* print fn */NULL); } for (i=0; i<pcstat_nelt; i++) { char buf[512], buf1[512]; struct stat_stat_t *stat; /* track the named statistical variable by text address */ /* find it... */ stat = stat_find_stat(sdb, pcstat_vars[i]); if (!stat) fatal("cannot locate any statistic named `%s'", pcstat_vars[i]); /* stat must be an integral type */ if (stat->sc != sc_int && stat->sc != sc_uint && stat->sc != sc_counter) fatal("`-pcstat' statistical variable `%s' is not an integral type", stat->name); /* register this stat */ pcstat_stats[i] = stat; pcstat_lastvals[i] = STATVAL(stat); /* declare the sparce text distribution */ sprintf(buf, "%s_by_pc", stat->name); sprintf(buf1, "%s (by text address)", stat->desc); pcstat_sdists[i] = stat_reg_sdist(sdb, buf, buf1, /* initial value */0, /* print format */(PF_COUNT|PF_PDF), /* format */"0x%p %u %.2f", /* print fn */NULL); } ld_reg_stats(sdb); mem_reg_stats(mem, sdb); }
void core_power_t::translate_stats(struct stat_sdb_t* sdb, system_core *core_stats, system_L2 *L2_stats) { struct stat_stat_t *stat; int coreID = core->id; struct core_knobs_t* knobs = core->knobs; (void) L2_stats; //XXX: Ignore McPAT's DVFS calculation for now. We do our own scaling in // compute_power(). That is, until we can validate that McPAT is doing // more or less the right thing. core_stats->vdd = core_power_t::default_vdd; stat = stat_find_core_stat(sdb, coreID, "oracle_total_uops"); core_stats->total_instructions = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "oracle_total_branches"); core_stats->branch_instructions = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "num_jeclear"); core_stats->branch_mispredictions = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "oracle_total_loads"); core_stats->load_instructions = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "oracle_total_refs"); core_stats->store_instructions = stat->variant.for_sqword.end_val - core_stats->load_instructions; stat = stat_find_core_stat(sdb, coreID, "oracle_num_uops"); core_stats->committed_instructions = stat->variant.for_sqword.end_val; // core cycles at potentially variable frequency stat = stat_find_core_stat(sdb, coreID, "sim_cycle"); core_stats->total_cycles = stat->variant.for_sqword.end_val; // get average frequency for this period stat = stat_find_stat(sdb, "sim_cycle"); core_stats->clock_rate = (int) ceil(core_stats->total_cycles * knobs->default_cpu_speed / (double) stat->variant.for_sqword.end_val); core_stats->idle_cycles = 0; core_stats->busy_cycles = core_stats->total_cycles - core_stats->idle_cycles; stat = stat_find_core_stat(sdb, coreID, "regfile_reads"); core_stats->int_regfile_reads = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "fp_regfile_reads"); core_stats->float_regfile_reads = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "regfile_writes"); core_stats->int_regfile_writes = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "fp_regfile_writes"); core_stats->float_regfile_writes = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "oracle_total_calls"); core_stats->function_calls = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "int_FU_occupancy"); core_stats->cdb_alu_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "fp_FU_occupancy"); core_stats->cdb_fpu_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "mul_FU_occupancy"); core_stats->cdb_mul_accesses = stat->variant.for_sqword.end_val; core_stats->ialu_accesses = core_stats->cdb_alu_accesses; core_stats->fpu_accesses = core_stats->cdb_fpu_accesses; core_stats->mul_accesses = core_stats->cdb_mul_accesses; stat = stat_find_core_stat(sdb, coreID, "commit_insn"); core_stats->pipeline_duty_cycle = (double) stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "sim_cycle"); core_stats->pipeline_duty_cycle /= stat->variant.for_sqword.end_val; core_stats->pipeline_duty_cycle /= knobs->commit.width; if (core->memory.ITLB) { stat = stat_find_core_stat(sdb, coreID, "ITLB.lookups"); core_stats->itlb.total_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "ITLB.misses"); core_stats->itlb.total_misses = stat->variant.for_sqword.end_val; } if (core->memory.DTLB) { stat = stat_find_core_stat(sdb, coreID, "DTLB.lookups"); core_stats->dtlb.total_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "DTLB.misses"); core_stats->dtlb.total_misses = stat->variant.for_sqword.end_val; } if (core->memory.IL1) { stat = stat_find_core_stat(sdb, coreID, "IL1.lookups"); core_stats->icache.read_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "IL1.misses"); core_stats->icache.read_misses = stat->variant.for_sqword.end_val; } if (core->memory.DL1) { stat = stat_find_core_stat(sdb, coreID, "DL1.load_lookups"); core_stats->dcache.read_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "DL1.load_misses"); core_stats->dcache.read_misses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "DL1.store_lookups"); core_stats->dcache.write_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "DL1.store_misses"); core_stats->dcache.write_misses = stat->variant.for_sqword.end_val; } if (core->fetch->bpred->get_dir_btb()) { stat = stat_find_core_stat(sdb, coreID, "BTB.lookups"); core_stats->BTB.read_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "BTB.updates"); core_stats->BTB.write_accesses = stat->variant.for_sqword.end_val; stat = stat_find_core_stat(sdb, coreID, "BTB.spec_updates"); core_stats->BTB.write_accesses += stat->variant.for_sqword.end_val; } }