/* 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); }
/* print the value of stat variable STAT */ void stat_print_stat(struct stat_sdb_t *sdb, /* stat database */ struct stat_stat_t *stat,/* stat variable */ FILE *fd) /* output stream */ { struct eval_value_t val; switch (stat->sc) { case sc_int: fprintf(fd, "%-22s ", stat->name); myfprintf(fd, stat->format, *stat->variant.for_int.var); fprintf(fd, " # %s", stat->desc); break; case sc_uint: fprintf(fd, "%-22s ", stat->name); myfprintf(fd, stat->format, *stat->variant.for_uint.var); fprintf(fd, " # %s", stat->desc); break; #ifdef HOST_HAS_QWORD case sc_qword: { char buf[128]; fprintf(fd, "%-22s ", stat->name); mysprintf(buf, stat->format, *stat->variant.for_qword.var); fprintf(fd, "%s # %s", buf, stat->desc); } break; case sc_sqword: { char buf[128]; fprintf(fd, "%-22s ", stat->name); mysprintf(buf, stat->format, *stat->variant.for_sqword.var); fprintf(fd, "%s # %s", buf, stat->desc); } break; #endif /* HOST_HAS_QWORD */ case sc_float: fprintf(fd, "%-22s ", stat->name); myfprintf(fd, stat->format, (double)*stat->variant.for_float.var); fprintf(fd, " # %s", stat->desc); break; case sc_double: fprintf(fd, "%-22s ", stat->name); myfprintf(fd, stat->format, *stat->variant.for_double.var); fprintf(fd, " # %s", stat->desc); break; case sc_dist: print_dist(stat, fd); break; case sc_sdist: print_sdist(stat, fd); break; case sc_formula: { /* instantiate a new evaluator to avoid recursion problems */ struct eval_state_t *es = eval_new(stat_eval_ident, sdb); char *endp; fprintf(fd, "%-22s ", stat->name); val = eval_expr(es, stat->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); /* done with the evaluator */ eval_delete(es); } break; default: panic("bogus stat class"); } fprintf(fd, "\n"); }
/* evaluate a stat as an expression */ struct eval_value_t stat_eval_ident(struct eval_state_t *es)/* an expression evaluator */ { struct stat_sdb_t *sdb = es->user_ptr; struct stat_stat_t *stat; static struct eval_value_t err_value = { et_int, { 0 } }; struct eval_value_t val; /* locate the stat variable */ for (stat = sdb->stats; stat != NULL; stat = stat->next) { if (!strcmp(stat->name, es->tok_buf)) { /* found it! */ break; } } if (!stat) { /* could not find stat variable */ eval_error = ERR_UNDEFVAR; return err_value; } /* else, return the value of stat */ /* convert the stat variable value to a typed expression value */ switch (stat->sc) { case sc_int: val.type = et_int; val.value.as_int = *stat->variant.for_int.var; break; case sc_uint: val.type = et_uint; val.value.as_uint = *stat->variant.for_uint.var; break; #ifdef HOST_HAS_QWORD case sc_qword: /* FIXME: cast to double, eval package doesn't support long long's */ val.type = et_double; #ifdef _MSC_VER /* FIXME: MSC does not implement qword_t to dbl conversion */ val.value.as_double = (double)(sqword_t)*stat->variant.for_qword.var; #else /* !_MSC_VER */ val.value.as_double = (double)*stat->variant.for_qword.var; #endif /* _MSC_VER */ break; case sc_sqword: /* FIXME: cast to double, eval package doesn't support long long's */ val.type = et_double; val.value.as_double = (double)*stat->variant.for_sqword.var; break; #endif /* HOST_HAS_QWORD */ case sc_float: val.type = et_float; val.value.as_float = *stat->variant.for_float.var; break; case sc_double: val.type = et_double; val.value.as_double = *stat->variant.for_double.var; break; case sc_dist: case sc_sdist: fatal("stat distributions not allowed in formula expressions"); break; case sc_formula: { /* instantiate a new evaluator to avoid recursion problems */ struct eval_state_t *es = eval_new(stat_eval_ident, sdb); char *endp; val = eval_expr(es, stat->variant.for_formula.formula, &endp); if (eval_error != ERR_NOERR || *endp != '\0') { /* pass through eval_error */ val = err_value; } /* else, use value returned */ eval_delete(es); } break; default: panic("bogus stat class"); } return val; }
/* delete a stats database */ void stat_delete(struct stat_sdb_t *sdb) /* stats database */ { int i; struct stat_stat_t *stat, *stat_next; struct bucket_t *bucket, *bucket_next; /* free all individual stat variables */ for (stat = sdb->stats; stat != NULL; stat = stat_next) { stat_next = stat->next; stat->next = NULL; /* free stat */ switch (stat->sc) { case sc_int: case sc_uint: #ifdef HOST_HAS_QWORD case sc_qword: case sc_sqword: #endif /* HOST_HAS_QWORD */ case sc_float: case sc_double: case sc_formula: /* no other storage to deallocate */ break; case sc_dist: /* free distribution array */ free(stat->variant.for_dist.arr); stat->variant.for_dist.arr = NULL; break; case sc_sdist: /* free all hash table buckets */ for (i=0; i<HTAB_SZ; i++) { for (bucket = stat->variant.for_sdist.sarr[i]; bucket != NULL; bucket = bucket_next) { bucket_next = bucket->next; bucket->next = NULL; free(bucket); } stat->variant.for_sdist.sarr[i] = NULL; } /* free hash table array */ free(stat->variant.for_sdist.sarr); stat->variant.for_sdist.sarr = NULL; break; default: panic("bogus stat class"); } /* free stat variable record */ free(stat); } sdb->stats = NULL; eval_delete(sdb->evaluator); sdb->evaluator = NULL; free(sdb); }