X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fcycles-stats.c;h=87d2c5101524138960ddfe7d541efd110dcc062e;hb=cdd9226791365a0eeefc95cbf2fb28151d51052b;hp=2dced2638143067e90142fd7cccfcf8feadc90d7;hpb=bfa095c53c90ee1ca8dbdb1af643d4bec51f6838;p=cacao.git diff --git a/src/vm/cycles-stats.c b/src/vm/cycles-stats.c index 2dced2638..87d2c5101 100644 --- a/src/vm/cycles-stats.c +++ b/src/vm/cycles-stats.c @@ -28,12 +28,11 @@ Changes: - $Id$ - */ #include "config.h" #include "vm/types.h" +#include "vm/global.h" #if defined(ENABLE_CYCLES_STATS) @@ -64,7 +63,7 @@ static double cycles_stats_get_cpu_MHz(void) { FILE *info; char line[CYCLES_STATS_MAXLINE + 1]; - + if (cycles_stats_cpu_MHz != 0.0) return cycles_stats_cpu_MHz; @@ -76,7 +75,7 @@ static double cycles_stats_get_cpu_MHz(void) while (!feof(info) && !ferror(info)) { if (fgets(line,CYCLES_STATS_MAXLINE,info) - && sscanf(line,"cpu MHz : %lf",&cycles_stats_cpu_MHz) == 1) + && sscanf(line,"cpu MHz : %lf",&cycles_stats_cpu_MHz) == 1) { fclose(info); fprintf(stderr,"CPU frequency used for statistics: %f MHz\n", @@ -97,31 +96,68 @@ got_no_cpuinfo: return cycles_stats_cpu_MHz; } +u8 cycles_stats_measurement_overhead = 0; + +static void cycles_stats_print_percentile(FILE *file, const char *name, + double percentile, u8 count, + u8 cumul, double cumulcycles, + bool isoverhead, bool printforall) +{ + u8 forall; + double cpuMHz = cycles_stats_get_cpu_MHz(); + u8 cycles_per_ms = cpuMHz * 1000; + + if (isoverhead) { + fprintf(file,"\t\t%14s = %6.1f\n", name, percentile); + } + else { + percentile -= cycles_stats_measurement_overhead; + + fprintf(file,"\t\t%14s = %14.1f (+%llu)", + name, percentile, + (unsigned long long)cycles_stats_measurement_overhead); + if (printforall) { + forall = cumulcycles - cumul * cycles_stats_measurement_overhead + + percentile * (count - cumul); + fprintf(file," (%-23s: %15llu cycles = %6lu msec)", + (count == cumul) ? "total" : "capped here & extrapol.", + (unsigned long long)forall, + (unsigned long)(forall / cycles_per_ms)); + } + fprintf(file,"\n"); + } +} + void cycles_stats_print(FILE *file, const char *name, int nbins, int div, - u4 *bins, u8 count, u8 min, u8 max) + u4 *bins, u8 count, u8 total, u8 min, u8 max, + int overhead) { s4 i; struct cycles_stats_percentile *pcd; u8 floor, ceiling; u8 p; u8 cumul; + double cumulcycles; double percentile; double cpuMHz = cycles_stats_get_cpu_MHz(); u8 cycles_per_ms = cpuMHz * 1000; fprintf(file,"\t%s: %llu calls\n", - name, (unsigned long long)count); - - fprintf(file,"\t%s cycles distribution:\n", name); + (overhead) ? "measurement overhead determined by" : name, + (unsigned long long)count); + + fprintf(file,"\t%s cycles distribution:\n", + (overhead) ? "measurement overhead" : name); - fprintf(file,"\t\t%14s = %llu\n", "min", (unsigned long long)min); + cycles_stats_print_percentile(file, "min", min, count, 0, 0, overhead, true); pcd = cycles_stats_percentile_defs; for (; pcd->name; pcd++) { floor = (count * pcd->pct) / 100; ceiling = (count * pcd->pct + 99) / 100; cumul = 0; + cumulcycles = 0; p = 0; percentile = -1.0; @@ -132,7 +168,7 @@ void cycles_stats_print(FILE *file, /* { invariant: `cumul` samples are < `p` } */ /* check if percentile lies exactly at the bin boundary */ - + if (floor == cumul && floor == ceiling) { percentile = p; break; @@ -144,13 +180,15 @@ void cycles_stats_print(FILE *file, percentile = p + (double)div/2.0; break; } - + cumul += bins[i]; p += div; + cumulcycles += bins[i] * (p - (double)div/2.0); + /* { invariant: `cumul` samples are < `p` } */ } - + /* check if percentile lies exactly at the bin boundary */ if (floor == cumul && floor == ceiling) { @@ -158,31 +196,43 @@ void cycles_stats_print(FILE *file, } if (percentile >= 0) { - u8 forall = percentile * count; - fprintf(file,"\t\t%14s = %6.1f (for all calls: %15llu cycles = %6lu msec)\n", - pcd->name, percentile, (unsigned long long)forall, - (unsigned long)(forall / cycles_per_ms)); + if (overhead && pcd->pct == 50) { + cycles_stats_measurement_overhead = percentile; + } + cycles_stats_print_percentile(file, pcd->name, percentile, + count, cumul, cumulcycles, + overhead, true); } else { + if (!overhead) + p -= cycles_stats_measurement_overhead; fprintf(file,"\t\t%14s = unknown (> %llu)\n", pcd->name, (unsigned long long)p); } } - - fprintf(file,"\t\t%14s = %llu\n", "max", (unsigned long long)max); - fprintf(file,"\t\t(assuming %llu cycles per ms)\n", (unsigned long long)cycles_per_ms); + + cycles_stats_print_percentile(file, "max", max, count, count, + total, overhead, true); + + if (!overhead) { + fprintf(file,"\t\t(assuming %llu cycles per ms)\n", + (unsigned long long)cycles_per_ms); + fprintf(file,"\t\t(assuming %llu cycles measurement overhead)\n", + (unsigned long long)cycles_stats_measurement_overhead); + } + fprintf(file,"\n"); - + cumul = 0; for (i=0; i= %5d: %10s (----) %10lu\n", + + fprintf(file,"\t\t>= %8d: %10s (----) %10lu\n", (int)(nbins * div), "OVER", (unsigned long) bins[nbins]);