"iops",
};
+enum {
+ MOVIE_SPINDLE,
+ MOVIE_RECT,
+ NUM_MOVIE_STYLES,
+};
+
+char *movie_styles[] = {
+ "spindle",
+ "rect",
+ NULL
+};
+
+static int movie_style = 0;
+
+static int lookup_movie_style(char *str)
+{
+ int i;
+
+ for (i = 0; i < NUM_MOVIE_STYLES; i++) {
+ if (strcmp(str, movie_styles[i]) == 0)
+ return i;
+ }
+ return -1;
+}
+
static int active_graphs[TOTAL_GRAPHS];
static int last_active_graph = IOPS_GRAPH_INDEX;
u64 last_time;
u64 ymin;
u64 ymax;
+ u64 max_bank;
+ u64 max_bank_offset;
list_for_each_entry(tf, &all_traces, list) {
trace = open_trace(tf->filename);
tf->trace = trace;
tf->seconds = SECONDS(last_time);
tf->stop_seconds = SECONDS(last_time);
- tf->max_offset = find_highest_offset(trace);
-
+ find_highest_offset(trace, &tf->max_offset, &max_bank,
+ &max_bank_offset);
filter_outliers(trace, tf->max_offset, &ymin, &ymax);
tf->max_offset = ymax;
static char *create_movie_temp_dir(void)
{
char *ret;
- char *pattern = strdup("btrfs-movie-XXXXXX");;
+ char *pattern = strdup("io-movie-XXXXXX");;
ret = mkdtemp(pattern);
if (!ret) {
static void plot_movie_history(struct plot *plot, struct list_head *list)
{
- float alpha = 0.1;
struct plot_history *ph;
+ if (num_histories > 2)
+ rewind_spindle_steps(num_histories - 1);
+
list_for_each_entry(ph, list, list) {
- if (ph->list.next == list)
- alpha = 1;
- svg_io_graph_movie_array(plot, ph, 1);
- alpha += 0.2;
- if (alpha > 1)
- alpha = 0.8;
+ if (movie_style == MOVIE_SPINDLE)
+ svg_io_graph_movie_array_spindle(plot, ph);
+ else
+ svg_io_graph_movie_array(plot, ph);
}
}
{
struct trace_file *tf;
- if (active_graphs[IO_GRAPH_INDEX] == 0)
- return;
-
setup_axis(plot);
svg_alloc_legend(plot, num_traces * 2);
static void plot_io(struct plot *plot, int seconds, u64 max_offset)
{
- plot->add_xlabel = last_active_graph == IO_GRAPH_INDEX;
+ if (active_graphs[IO_GRAPH_INDEX] == 0)
+ return;
+ plot->add_xlabel = last_active_graph == IO_GRAPH_INDEX;
__plot_io(plot, seconds, max_offset);
close_plot(plot);
}
char line[128];
u64 max = 0;
- if (active_graphs[TPUT_GRAPH_INDEX] == 0)
- return;
-
if (num_traces > 1)
svg_alloc_legend(plot, num_traces);
list_for_each_entry(tf, &all_traces, list) {
set_xticks(plot, 9, 0, seconds);
list_for_each_entry(tf, &all_traces, list) {
- svg_line_graph(plot, tf->tput_gld, tf->read_color);
+ svg_line_graph(plot, tf->tput_gld, tf->read_color, 0, 0);
if (num_traces > 1)
svg_add_legend(plot, tf->label, "", tf->read_color);
}
static void plot_tput(struct plot *plot, int seconds)
{
+ if (active_graphs[TPUT_GRAPH_INDEX] == 0)
+ return;
+
plot->add_xlabel = last_active_graph == TPUT_GRAPH_INDEX;
__plot_tput(plot, seconds);
close_plot(plot);
static void mencode_movie(char *movie_dir)
{
fprintf(stderr, "Creating movie %s\n", movie_dir);
- snprintf(line, line_len, "ffmpeg -r 25 -y -i %s/%%10d-%s.svg.png -b:v 250k "
+ snprintf(line, line_len, "ffmpeg -r 20 -y -i %s/%%10d-%s.svg.png -b:v 250k "
"-vcodec libx264 %s", movie_dir, output_filename, output_filename);
system(line);
}
struct plot_history *write_history;
int batch_i;
int movie_len = 30;
- int movie_frames_per_sec = 16;
+ int movie_frames_per_sec = 20;
int total_frames = movie_len * movie_frames_per_sec;
int rows, cols;
int batch_count;
set_plot_output(plot, line);
set_plot_title(plot, graph_title);
- setup_axis(plot);
+ if (movie_style == MOVIE_SPINDLE)
+ setup_axis_spindle(plot);
+ else
+ setup_axis(plot);
+
svg_alloc_legend(plot, num_traces * 2);
read_history = alloc_plot_history(tf->read_color);
batch_i = 0;
while (i < cols && batch_i < batch_count) {
- /* print just this column */
svg_io_graph_movie(tf->gdd_reads, read_history, i);
-
svg_io_graph_movie(tf->gdd_writes, write_history, i);
i++;
batch_i++;
svg_write_legend(plot);
close_plot(plot);
- set_graph_size(cols, rows / 3);
+ set_graph_size(cols, rows / 7);
plot->add_xlabel = 1;
__plot_tput(plot, tf->gdd_reads->seconds);
svg_write_time_line(plot, i);
set_graph_size(cols, rows);
close_plot(plot);
+ close_plot_file(plot);
}
free_all_plot_history(&movie_history_reads);
free_all_plot_history(&movie_history_writes);
int active_index, int gld_index)
{
struct trace_file *tf;
- char line[128];
int max = 0;
int i;
int gld_i;
cpu_color_index = 0;
list_for_each_entry(tf, &all_traces, list) {
for (i = 0; i < tf->mpstat_gld[0]->stop_seconds; i++) {
- avg += tf->mpstat_gld[gld_index]->data[i].sum;
+ if (tf->mpstat_gld[gld_index]->data[i].count) {
+ avg += (tf->mpstat_gld[gld_index]->data[i].sum /
+ tf->mpstat_gld[gld_index]->data[i].count);
+ }
}
avg /= tf->mpstat_gld[gld_index]->stop_seconds;
color = pick_cpu_color();
- svg_line_graph(plot, tf->mpstat_gld[0], color);
+ svg_line_graph(plot, tf->mpstat_gld[0], color, 0, 0);
svg_add_legend(plot, tf->label, " avg", color);
for (i = 1; i < tf->trace->mpstat_num_cpus + 1; i++) {
double this_avg = 0;
for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++)
- this_avg += gld->data[i].sum;
+ this_avg += gld->data[i].sum /
+ gld->data[i].count;;
this_avg /= gld->stop_seconds;
for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++) {
- if (this_avg > avg + 30 ||
- gld->data[gld_i].sum > 95) {
+ double val;
+
+ if (gld->data[gld_i].count == 0)
+ continue;
+ val = (double)gld->data[gld_i].sum /
+ gld->data[gld_i].count;
+
+ if (this_avg > avg + 30 || val > 95) {
color = pick_cpu_color();
- svg_line_graph(plot, gld, color);
- snprintf(line, 128, " CPU %d\n", i - 1);
+ svg_line_graph(plot, gld, color, avg + 30, 95);
+ snprintf(line, line_len, " CPU %d\n", i - 1);
svg_add_legend(plot, tf->label, line, color);
plotted++;
break;
if (plot->add_xlabel)
set_xlabel(plot, "Time (seconds)");
- if (plot->legend_index <= 8)
- svg_write_legend(plot);
- else
- svg_free_legend(plot);
+ svg_write_legend(plot);
+ svg_free_legend(plot);
close_plot(plot);
}
set_xticks(plot, 9, 0, seconds);
list_for_each_entry(tf, &all_traces, list) {
- svg_line_graph(plot, tf->latency_gld, tf->read_color);
+ svg_line_graph(plot, tf->latency_gld, tf->read_color, 0, 0);
if (num_traces > 1)
svg_add_legend(plot, tf->label, "", tf->read_color);
}
set_xticks(plot, 9, 0, seconds);
list_for_each_entry(tf, &all_traces, list) {
- svg_line_graph(plot, tf->queue_depth_gld, tf->read_color);
+ svg_line_graph(plot, tf->queue_depth_gld, tf->read_color, 0, 0);
if (num_traces > 1)
svg_add_legend(plot, tf->label, "", tf->read_color);
}
set_xticks(plot, 9, 0, seconds);
list_for_each_entry(tf, &all_traces, list) {
- svg_line_graph(plot, tf->iop_gld, tf->read_color);
+ svg_line_graph(plot, tf->iop_gld, tf->read_color, 0, 0);
if (num_traces > 1)
svg_add_legend(plot, tf->label, "", tf->read_color);
}
HELP_LONG_OPT = 1,
};
-char *option_string = "T:t:o:l:r:O:N:d:p:mh:w:";
+char *option_string = "T:t:o:l:r:O:N:d:p:m::h:w:";
static struct option long_options[] = {
{"title", required_argument, 0, 'T'},
{"trace", required_argument, 0, 't'},
{"only-graph", required_argument, 0, 'O'},
{"device", required_argument, 0, 'd'},
{"prog", required_argument, 0, 'p'},
- {"movie", no_argument, 0, 'm'},
+ {"movie", optional_argument, 0, 'm'},
{"width", required_argument, 0, 'w'},
{"height", required_argument, 0, 'h'},
{"help", no_argument, 0, HELP_LONG_OPT},
"\t-l (--label): trace label in the graph\n"
"\t-o (--output): output file name (SVG only)\n"
"\t-p (--prog): program to run while blktrace is run\n"
- "\t-p (--movie): create IO animations\n"
+ "\t-p (--movie [=spindle|rect]): create IO animations\n"
"\t-r (--rolling): number of seconds in the rolling averge\n"
"\t-T (--title): graph title\n"
"\t-N (--no-graph): skip a single graph (io, tput, latency, queue_depth, iops)\n"
break;
case 'm':
make_movie = 1;
+ if (optarg) {
+ movie_style = lookup_movie_style(optarg);
+ if (movie_style < 0) {
+ fprintf(stderr, "Unknown movie style %s\n", optarg);
+ print_usage();
+ }
+ }
+ fprintf(stderr, "Using movie style: %s\n",
+ movie_styles[movie_style]);
break;
case 'h':
opt_graph_height = atoi(optarg);
last_active_graph = last_graph();
if (make_movie) {
set_io_graph_scale(256);
- set_graph_size(700, 250);
+ if (movie_style == MOVIE_SPINDLE)
+ set_graph_size(550, 550);
+ else
+ set_graph_size(700, 400);
}
if (opt_graph_height)
set_graph_height(opt_graph_height);
/* once for all */
close_plot(plot);
+ close_plot_file(plot);
return 0;
}