cyclictest: add option for dumping the histogram in a file
On Wed, Sep 16, 2015 at 01:05:51AM +0200, John Kacur wrote: > On Mon, 31 Aug 2015, Josh Cartwright wrote: > > From: Gratian Crisan <gratian.crisan@ni.com> > > > > Add an option '-J' or '--histfile' to dump the latency histogram to <path> > > instead of stdout. This allows for live update of the current min, avg, and max > > numbers while retaining the option to save histogram data for later analysis. > > > > Signed-off-by: Gratian Crisan <gratian.crisan@ni.com> > > Signed-off-by: Josh Cartwright <joshc@ni.com> [..] > > We worked really hard to remove the large amount of options, and we may > have been over zealous in some cases (Carsten?). Fair enough, cyclictest has way too many knobs. Regardless, we've at least found this particular option useful. > If I were to accept this patch, I would at least like you to remove > the short form option, and just have it in the long form. Here is a v2 with the short form -J dropped. Thanks, Josh -- 8< -- From: Gratian Crisan <gratian.crisan@ni.com> Subject: [PATCH v2] cyclictest: add option for dumping the histogram in a file Add an option '--histfile' to dump the latency histogram to <path> instead of stdout. This allows for live update of the current min, avg, and max numbers while retaining the option to save histogram data for later analysis. Signed-off-by: Gratian Crisan <gratian.crisan@ni.com> Signed-off-by: Josh Cartwright <joshc@ni.com> Signed-off-by: John Kacur <jkacur@redhat.com>
This commit is contained in:
parent
b49f58efd6
commit
864fc87eed
|
@ -188,6 +188,7 @@ static int aligned = 0;
|
|||
static int secaligned = 0;
|
||||
static int offset = 0;
|
||||
static int laptop = 0;
|
||||
static int use_histfile = 0;
|
||||
|
||||
static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
@ -210,6 +211,7 @@ static char *procfileprefix = "/proc/sys/kernel/";
|
|||
static char *fileprefix;
|
||||
static char tracer[MAX_PATH];
|
||||
static char fifopath[MAX_PATH];
|
||||
static char histfile[MAX_PATH];
|
||||
static char **traceptr;
|
||||
static int traceopt_count;
|
||||
static int traceopt_size;
|
||||
|
@ -1049,6 +1051,7 @@ static void display_help(int error)
|
|||
" (with same priority about many threads)\n"
|
||||
" US is the max time to be be tracked in microseconds\n"
|
||||
"-H --histofall=US same as -h except with an additional summary column\n"
|
||||
" --histfile=<path> dump the latency histogram to <path> instead of stdout\n"
|
||||
"-i INTV --interval=INTV base interval of thread in us default=1000\n"
|
||||
"-I --irqsoff Irqsoff tracing (used with -b)\n"
|
||||
"-l LOOPS --loops=LOOPS number of loops: default=0(endless)\n"
|
||||
|
@ -1214,13 +1217,13 @@ static char *policyname(int policy)
|
|||
enum option_values {
|
||||
OPT_AFFINITY=1, OPT_NOTRACE, OPT_BREAKTRACE, OPT_PREEMPTIRQ, OPT_CLOCK,
|
||||
OPT_CONTEXT, OPT_DISTANCE, OPT_DURATION, OPT_LATENCY, OPT_EVENT,
|
||||
OPT_FTRACE, OPT_FIFO, OPT_HISTOGRAM, OPT_HISTOFALL, OPT_INTERVAL,
|
||||
OPT_IRQSOFF, OPT_LOOPS, OPT_MLOCKALL, OPT_REFRESH, OPT_NANOSLEEP,
|
||||
OPT_NSECS, OPT_OSCOPE, OPT_TRACEOPT, OPT_PRIORITY, OPT_PREEMPTOFF,
|
||||
OPT_QUIET, OPT_PRIOSPREAD, OPT_RELATIVE, OPT_RESOLUTION, OPT_SYSTEM,
|
||||
OPT_SMP, OPT_THREADS, OPT_TRACER, OPT_UNBUFFERED, OPT_NUMA, OPT_VERBOSE,
|
||||
OPT_WAKEUP, OPT_WAKEUPRT, OPT_DBGCYCLIC, OPT_POLICY, OPT_HELP, OPT_NUMOPTS,
|
||||
OPT_ALIGNED, OPT_LAPTOP, OPT_SECALIGNED,
|
||||
OPT_FTRACE, OPT_FIFO, OPT_HISTOGRAM, OPT_HISTOFALL, OPT_HISTFILE,
|
||||
OPT_INTERVAL, OPT_IRQSOFF, OPT_LOOPS, OPT_MLOCKALL, OPT_REFRESH, OPT_NANOSLEEP,
|
||||
OPT_NSECS, OPT_OSCOPE, OPT_TRACEOPT, OPT_PRIORITY, OPT_PREEMPTOFF, OPT_QUIET,
|
||||
OPT_PRIOSPREAD, OPT_RELATIVE, OPT_RESOLUTION, OPT_SYSTEM, OPT_SMP, OPT_THREADS,
|
||||
OPT_TRACER, OPT_UNBUFFERED, OPT_NUMA, OPT_VERBOSE, OPT_WAKEUP, OPT_WAKEUPRT,
|
||||
OPT_DBGCYCLIC, OPT_POLICY, OPT_HELP, OPT_NUMOPTS, OPT_ALIGNED, OPT_LAPTOP,
|
||||
OPT_SECALIGNED,
|
||||
};
|
||||
|
||||
/* Process commandline options */
|
||||
|
@ -1251,6 +1254,7 @@ static void process_options (int argc, char *argv[], int max_cpus)
|
|||
{"fifo", required_argument, NULL, OPT_FIFO },
|
||||
{"histogram", required_argument, NULL, OPT_HISTOGRAM },
|
||||
{"histofall", required_argument, NULL, OPT_HISTOFALL },
|
||||
{"histfile", required_argument, NULL, OPT_HISTFILE },
|
||||
{"interval", required_argument, NULL, OPT_INTERVAL },
|
||||
{"irqsoff", no_argument, NULL, OPT_IRQSOFF },
|
||||
{"laptop", no_argument, NULL, OPT_LAPTOP },
|
||||
|
@ -1348,6 +1352,10 @@ static void process_options (int argc, char *argv[], int max_cpus)
|
|||
case 'h':
|
||||
case OPT_HISTOGRAM:
|
||||
histogram = atoi(optarg); break;
|
||||
case OPT_HISTFILE:
|
||||
use_histfile = 1;
|
||||
strncpy(histfile, optarg, strlen(optarg));
|
||||
break;
|
||||
case 'i':
|
||||
case OPT_INTERVAL:
|
||||
interval = atoi(optarg); break;
|
||||
|
@ -1652,74 +1660,88 @@ static void print_hist(struct thread_param *par[], int nthreads)
|
|||
int i, j;
|
||||
unsigned long long int log_entries[nthreads+1];
|
||||
unsigned long maxmax, alloverflows;
|
||||
FILE *fd;
|
||||
|
||||
bzero(log_entries, sizeof(log_entries));
|
||||
|
||||
printf("# Histogram\n");
|
||||
if (use_histfile) {
|
||||
fd = fopen(histfile, "w");
|
||||
if (!fd) {
|
||||
perror("opening histogram file:");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
fd = stdout;
|
||||
}
|
||||
|
||||
fprintf(fd, "# Histogram\n");
|
||||
for (i = 0; i < histogram; i++) {
|
||||
unsigned long long int allthreads = 0;
|
||||
|
||||
printf("%06d ", i);
|
||||
fprintf(fd, "%06d ", i);
|
||||
|
||||
for (j = 0; j < nthreads; j++) {
|
||||
unsigned long curr_latency=par[j]->stats->hist_array[i];
|
||||
printf("%06lu", curr_latency);
|
||||
fprintf(fd, "%06lu", curr_latency);
|
||||
if (j < nthreads - 1)
|
||||
printf("\t");
|
||||
fprintf(fd, "\t");
|
||||
log_entries[j] += curr_latency;
|
||||
allthreads += curr_latency;
|
||||
}
|
||||
if (histofall && nthreads > 1) {
|
||||
printf("\t%06llu", allthreads);
|
||||
fprintf(fd, "\t%06llu", allthreads);
|
||||
log_entries[nthreads] += allthreads;
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
printf("# Total:");
|
||||
fprintf(fd, "# Total:");
|
||||
for (j = 0; j < nthreads; j++)
|
||||
printf(" %09llu", log_entries[j]);
|
||||
fprintf(fd, " %09llu", log_entries[j]);
|
||||
if (histofall && nthreads > 1)
|
||||
printf(" %09llu", log_entries[nthreads]);
|
||||
printf("\n");
|
||||
printf("# Min Latencies:");
|
||||
fprintf(fd, " %09llu", log_entries[nthreads]);
|
||||
fprintf(fd, "\n");
|
||||
fprintf(fd, "# Min Latencies:");
|
||||
for (j = 0; j < nthreads; j++)
|
||||
printf(" %05lu", par[j]->stats->min);
|
||||
printf("\n");
|
||||
printf("# Avg Latencies:");
|
||||
fprintf(fd, " %05lu", par[j]->stats->min);
|
||||
fprintf(fd, "\n");
|
||||
fprintf(fd, "# Avg Latencies:");
|
||||
for (j = 0; j < nthreads; j++)
|
||||
printf(" %05lu", par[j]->stats->cycles ?
|
||||
fprintf(fd, " %05lu", par[j]->stats->cycles ?
|
||||
(long)(par[j]->stats->avg/par[j]->stats->cycles) : 0);
|
||||
printf("\n");
|
||||
printf("# Max Latencies:");
|
||||
fprintf(fd, "\n");
|
||||
fprintf(fd, "# Max Latencies:");
|
||||
maxmax = 0;
|
||||
for (j = 0; j < nthreads; j++) {
|
||||
printf(" %05lu", par[j]->stats->max);
|
||||
fprintf(fd, " %05lu", par[j]->stats->max);
|
||||
if (par[j]->stats->max > maxmax)
|
||||
maxmax = par[j]->stats->max;
|
||||
}
|
||||
if (histofall && nthreads > 1)
|
||||
printf(" %05lu", maxmax);
|
||||
printf("\n");
|
||||
printf("# Histogram Overflows:");
|
||||
fprintf(fd, " %05lu", maxmax);
|
||||
fprintf(fd, "\n");
|
||||
fprintf(fd, "# Histogram Overflows:");
|
||||
alloverflows = 0;
|
||||
for (j = 0; j < nthreads; j++) {
|
||||
printf(" %05lu", par[j]->stats->hist_overflow);
|
||||
fprintf(fd, " %05lu", par[j]->stats->hist_overflow);
|
||||
alloverflows += par[j]->stats->hist_overflow;
|
||||
}
|
||||
if (histofall && nthreads > 1)
|
||||
printf(" %05lu", alloverflows);
|
||||
printf("\n");
|
||||
fprintf(fd, " %05lu", alloverflows);
|
||||
fprintf(fd, "\n");
|
||||
|
||||
printf("# Histogram Overflow at cycle number:\n");
|
||||
fprintf(fd, "# Histogram Overflow at cycle number:\n");
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
printf("# Thread %d:", i);
|
||||
fprintf(fd, "# Thread %d:", i);
|
||||
for (j = 0; j < par[i]->stats->num_outliers; j++)
|
||||
printf(" %05lu", par[i]->stats->outliers[j]);
|
||||
fprintf(fd, " %05lu", par[i]->stats->outliers[j]);
|
||||
if (par[i]->stats->num_outliers < par[i]->stats->hist_overflow)
|
||||
printf(" # %05lu others", par[i]->stats->hist_overflow - par[i]->stats->num_outliers);
|
||||
printf("\n");
|
||||
fprintf(fd, " # %05lu others", par[i]->stats->hist_overflow - par[i]->stats->num_outliers);
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(fd, "\n");
|
||||
|
||||
if (use_histfile)
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
static void print_stat(FILE *fp, struct thread_param *par, int index, int verbose, int quiet)
|
||||
|
|
Loading…
Reference in New Issue