summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py729
1 files changed, 729 insertions, 0 deletions
diff --git a/src/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py b/src/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py
new file mode 100644
index 000000000..37166bcb4
--- /dev/null
+++ b/src/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py
@@ -0,0 +1,729 @@
+# Copyright (c) Meta Platforms, Inc. and affiliates.
+#
+# This source code is licensed under both the GPLv2 (found in the
+# COPYING file in the root directory) and Apache 2.0 License
+# (found in the LICENSE.Apache file in the root directory).
+
+#!/usr/bin/env python3
+
+import csv
+import math
+import os
+import random
+import sys
+
+import matplotlib
+
+matplotlib.use("Agg")
+import matplotlib.backends.backend_pdf
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import seaborn as sns
+
+
+# Make sure a legend has the same color across all generated graphs.
+def get_cmap(n, name="hsv"):
+ """Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
+ RGB color; the keyword argument name must be a standard mpl colormap name."""
+ return plt.cm.get_cmap(name, n)
+
+
+color_index = 0
+bar_color_maps = {}
+colors = []
+n_colors = 360
+linear_colors = get_cmap(n_colors)
+for i in range(n_colors):
+ colors.append(linear_colors(i))
+# Shuffle the colors so that adjacent bars in a graph are obvious to differentiate.
+random.shuffle(colors)
+
+
+def num_to_gb(n):
+ one_gb = 1024 * 1024 * 1024
+ if float(n) % one_gb == 0:
+ return "{}".format(n / one_gb)
+ # Keep two decimal points.
+ return "{0:.2f}".format(float(n) / one_gb)
+
+
+def plot_miss_stats_graphs(
+ csv_result_dir, output_result_dir, file_prefix, file_suffix, ylabel, pdf_file_name
+):
+ miss_ratios = {}
+ for file in os.listdir(csv_result_dir):
+ if not file.startswith(file_prefix):
+ continue
+ if not file.endswith(file_suffix):
+ continue
+ print("Processing file {}/{}".format(csv_result_dir, file))
+ mrc_file_path = csv_result_dir + "/" + file
+ with open(mrc_file_path, "r") as csvfile:
+ rows = csv.reader(csvfile, delimiter=",")
+ for row in rows:
+ cache_name = row[0]
+ num_shard_bits = int(row[1])
+ ghost_capacity = int(row[2])
+ capacity = int(row[3])
+ miss_ratio = float(row[4])
+ config = "{}-{}-{}".format(cache_name, num_shard_bits, ghost_capacity)
+ if config not in miss_ratios:
+ miss_ratios[config] = {}
+ miss_ratios[config]["x"] = []
+ miss_ratios[config]["y"] = []
+ miss_ratios[config]["x"].append(capacity)
+ miss_ratios[config]["y"].append(miss_ratio)
+ fig = plt.figure()
+ for config in miss_ratios:
+ plt.plot(
+ miss_ratios[config]["x"], miss_ratios[config]["y"], label=config
+ )
+ plt.xlabel("Cache capacity")
+ plt.ylabel(ylabel)
+ plt.xscale("log", basex=2)
+ plt.ylim(ymin=0)
+ plt.title("{}".format(file))
+ plt.legend()
+ fig.savefig(
+ output_result_dir + "/{}.pdf".format(pdf_file_name), bbox_inches="tight"
+ )
+
+
+def plot_miss_stats_diff_lru_graphs(
+ csv_result_dir, output_result_dir, file_prefix, file_suffix, ylabel, pdf_file_name
+):
+ miss_ratios = {}
+ for file in os.listdir(csv_result_dir):
+ if not file.startswith(file_prefix):
+ continue
+ if not file.endswith(file_suffix):
+ continue
+ print("Processing file {}/{}".format(csv_result_dir, file))
+ mrc_file_path = csv_result_dir + "/" + file
+ with open(mrc_file_path, "r") as csvfile:
+ rows = csv.reader(csvfile, delimiter=",")
+ for row in rows:
+ cache_name = row[0]
+ num_shard_bits = int(row[1])
+ ghost_capacity = int(row[2])
+ capacity = int(row[3])
+ miss_ratio = float(row[4])
+ config = "{}-{}-{}".format(cache_name, num_shard_bits, ghost_capacity)
+ if config not in miss_ratios:
+ miss_ratios[config] = {}
+ miss_ratios[config]["x"] = []
+ miss_ratios[config]["y"] = []
+ miss_ratios[config]["x"].append(capacity)
+ miss_ratios[config]["y"].append(miss_ratio)
+ if "lru-0-0" not in miss_ratios:
+ return
+ fig = plt.figure()
+ for config in miss_ratios:
+ diffs = [0] * len(miss_ratios["lru-0-0"]["x"])
+ for i in range(len(miss_ratios["lru-0-0"]["x"])):
+ for j in range(len(miss_ratios[config]["x"])):
+ if miss_ratios["lru-0-0"]["x"][i] == miss_ratios[config]["x"][j]:
+ diffs[i] = (
+ miss_ratios[config]["y"][j] - miss_ratios["lru-0-0"]["y"][i]
+ )
+ break
+ plt.plot(miss_ratios["lru-0-0"]["x"], diffs, label=config)
+ plt.xlabel("Cache capacity")
+ plt.ylabel(ylabel)
+ plt.xscale("log", basex=2)
+ plt.title("{}".format(file))
+ plt.legend()
+ fig.savefig(
+ output_result_dir + "/{}.pdf".format(pdf_file_name), bbox_inches="tight"
+ )
+
+
+def sanitize(label):
+ # matplotlib cannot plot legends that is prefixed with "_"
+ # so we need to remove them here.
+ index = 0
+ for i in range(len(label)):
+ if label[i] == "_":
+ index += 1
+ else:
+ break
+ data = label[index:]
+ # The value of uint64_max in c++.
+ if "18446744073709551615" in data:
+ return "max"
+ return data
+
+
+# Read the csv file vertically, i.e., group the data by columns.
+def read_data_for_plot_vertical(csvfile):
+ x = []
+ labels = []
+ label_stats = {}
+ csv_rows = csv.reader(csvfile, delimiter=",")
+ data_rows = []
+ for row in csv_rows:
+ data_rows.append(row)
+ # header
+ for i in range(1, len(data_rows[0])):
+ labels.append(sanitize(data_rows[0][i]))
+ label_stats[i - 1] = []
+ for i in range(1, len(data_rows)):
+ for j in range(len(data_rows[i])):
+ if j == 0:
+ x.append(sanitize(data_rows[i][j]))
+ continue
+ label_stats[j - 1].append(float(data_rows[i][j]))
+ return x, labels, label_stats
+
+
+# Read the csv file horizontally, i.e., group the data by rows.
+def read_data_for_plot_horizontal(csvfile):
+ x = []
+ labels = []
+ label_stats = {}
+ csv_rows = csv.reader(csvfile, delimiter=",")
+ data_rows = []
+ for row in csv_rows:
+ data_rows.append(row)
+ # header
+ for i in range(1, len(data_rows)):
+ labels.append(sanitize(data_rows[i][0]))
+ label_stats[i - 1] = []
+ for i in range(1, len(data_rows[0])):
+ x.append(sanitize(data_rows[0][i]))
+ for i in range(1, len(data_rows)):
+ for j in range(len(data_rows[i])):
+ if j == 0:
+ # label
+ continue
+ label_stats[i - 1].append(float(data_rows[i][j]))
+ return x, labels, label_stats
+
+
+def read_data_for_plot(csvfile, vertical):
+ if vertical:
+ return read_data_for_plot_vertical(csvfile)
+ return read_data_for_plot_horizontal(csvfile)
+
+
+def plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix,
+ filename_suffix,
+ pdf_name,
+ xlabel,
+ ylabel,
+ title,
+ vertical,
+ legend,
+):
+ global color_index, bar_color_maps, colors
+ pdf = matplotlib.backends.backend_pdf.PdfPages(output_result_dir + "/" + pdf_name)
+ for file in os.listdir(csv_result_dir):
+ if not file.endswith(filename_suffix):
+ continue
+ if not file.startswith(filename_prefix):
+ continue
+ print("Processing file {}/{}".format(csv_result_dir, file))
+ with open(csv_result_dir + "/" + file, "r") as csvfile:
+ x, labels, label_stats = read_data_for_plot(csvfile, vertical)
+ if len(x) == 0 or len(labels) == 0:
+ continue
+ # plot figure
+ fig = plt.figure()
+ for label_index in label_stats:
+ # Assign a unique color to this label.
+ if labels[label_index] not in bar_color_maps:
+ bar_color_maps[labels[label_index]] = colors[color_index]
+ color_index += 1
+ plt.plot(
+ [int(x[i]) for i in range(len(x) - 1)],
+ label_stats[label_index][:-1],
+ label=labels[label_index],
+ color=bar_color_maps[labels[label_index]],
+ )
+
+ # Translate time unit into x labels.
+ if "_60" in file:
+ plt.xlabel("{} (Minute)".format(xlabel))
+ if "_3600" in file:
+ plt.xlabel("{} (Hour)".format(xlabel))
+ plt.ylabel(ylabel)
+ plt.title("{} {}".format(title, file))
+ if legend:
+ plt.legend()
+ pdf.savefig(fig)
+ pdf.close()
+
+
+def plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix,
+ pdf_name,
+ xlabel,
+ ylabel,
+ title,
+ vertical,
+ x_prefix,
+):
+ global color_index, bar_color_maps, colors
+ pdf = matplotlib.backends.backend_pdf.PdfPages(
+ "{}/{}".format(output_result_dir, pdf_name)
+ )
+ for file in os.listdir(csv_result_dir):
+ if not file.endswith(filename_suffix):
+ continue
+ with open(csv_result_dir + "/" + file, "r") as csvfile:
+ print("Processing file {}/{}".format(csv_result_dir, file))
+ x, labels, label_stats = read_data_for_plot(csvfile, vertical)
+ if len(x) == 0 or len(label_stats) == 0:
+ continue
+ # Plot figure
+ fig = plt.figure()
+ ind = np.arange(len(x)) # the x locations for the groups
+ width = 0.5 # the width of the bars: can also be len(x) sequence
+ bars = []
+ bottom_bars = []
+ for _i in label_stats[0]:
+ bottom_bars.append(0)
+ for i in range(0, len(label_stats)):
+ # Assign a unique color to this label.
+ if labels[i] not in bar_color_maps:
+ bar_color_maps[labels[i]] = colors[color_index]
+ color_index += 1
+ p = plt.bar(
+ ind,
+ label_stats[i],
+ width,
+ bottom=bottom_bars,
+ color=bar_color_maps[labels[i]],
+ )
+ bars.append(p[0])
+ for j in range(len(label_stats[i])):
+ bottom_bars[j] += label_stats[i][j]
+ plt.xlabel(xlabel)
+ plt.ylabel(ylabel)
+ plt.xticks(
+ ind, [x_prefix + x[i] for i in range(len(x))], rotation=20, fontsize=8
+ )
+ plt.legend(bars, labels)
+ plt.title("{} filename:{}".format(title, file))
+ pdf.savefig(fig)
+ pdf.close()
+
+
+def plot_heatmap(csv_result_dir, output_result_dir, filename_suffix, pdf_name, title):
+ pdf = matplotlib.backends.backend_pdf.PdfPages(
+ "{}/{}".format(output_result_dir, pdf_name)
+ )
+ for file in os.listdir(csv_result_dir):
+ if not file.endswith(filename_suffix):
+ continue
+ csv_file_name = "{}/{}".format(csv_result_dir, file)
+ print("Processing file {}/{}".format(csv_result_dir, file))
+ corr_table = pd.read_csv(csv_file_name)
+ corr_table = corr_table.pivot("label", "corr", "value")
+ fig = plt.figure()
+ sns.heatmap(corr_table, annot=True, linewidths=0.5, fmt=".2")
+ plt.title("{} filename:{}".format(title, file))
+ pdf.savefig(fig)
+ pdf.close()
+
+
+def plot_timeline(csv_result_dir, output_result_dir):
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="access_timeline",
+ pdf_name="access_time.pdf",
+ xlabel="Time",
+ ylabel="Throughput",
+ title="Access timeline with group by label",
+ vertical=False,
+ legend=True,
+ )
+
+
+def convert_to_0_if_nan(n):
+ if math.isnan(n):
+ return 0.0
+ return n
+
+
+def plot_correlation(csv_result_dir, output_result_dir):
+ # Processing the correlation input first.
+ label_str_file = {}
+ for file in os.listdir(csv_result_dir):
+ if not file.endswith("correlation_input"):
+ continue
+ csv_file_name = "{}/{}".format(csv_result_dir, file)
+ print("Processing file {}/{}".format(csv_result_dir, file))
+ corr_table = pd.read_csv(csv_file_name)
+ label_str = file.split("_")[0]
+ label = file[len(label_str) + 1 :]
+ label = label[: len(label) - len("_correlation_input")]
+
+ output_file = "{}/{}_correlation_output".format(csv_result_dir, label_str)
+ if output_file not in label_str_file:
+ f = open("{}/{}_correlation_output".format(csv_result_dir, label_str), "w+")
+ label_str_file[output_file] = f
+ f.write("label,corr,value\n")
+ f = label_str_file[output_file]
+ f.write(
+ "{},{},{}\n".format(
+ label,
+ "LA+A",
+ convert_to_0_if_nan(
+ corr_table["num_accesses_since_last_access"].corr(
+ corr_table["num_accesses_till_next_access"], method="spearman"
+ )
+ ),
+ )
+ )
+ f.write(
+ "{},{},{}\n".format(
+ label,
+ "PA+A",
+ convert_to_0_if_nan(
+ corr_table["num_past_accesses"].corr(
+ corr_table["num_accesses_till_next_access"], method="spearman"
+ )
+ ),
+ )
+ )
+ f.write(
+ "{},{},{}\n".format(
+ label,
+ "LT+A",
+ convert_to_0_if_nan(
+ corr_table["elapsed_time_since_last_access"].corr(
+ corr_table["num_accesses_till_next_access"], method="spearman"
+ )
+ ),
+ )
+ )
+ f.write(
+ "{},{},{}\n".format(
+ label,
+ "LA+T",
+ convert_to_0_if_nan(
+ corr_table["num_accesses_since_last_access"].corr(
+ corr_table["elapsed_time_till_next_access"], method="spearman"
+ )
+ ),
+ )
+ )
+ f.write(
+ "{},{},{}\n".format(
+ label,
+ "LT+T",
+ convert_to_0_if_nan(
+ corr_table["elapsed_time_since_last_access"].corr(
+ corr_table["elapsed_time_till_next_access"], method="spearman"
+ )
+ ),
+ )
+ )
+ f.write(
+ "{},{},{}\n".format(
+ label,
+ "PA+T",
+ convert_to_0_if_nan(
+ corr_table["num_past_accesses"].corr(
+ corr_table["elapsed_time_till_next_access"], method="spearman"
+ )
+ ),
+ )
+ )
+ for label_str in label_str_file:
+ label_str_file[label_str].close()
+
+ plot_heatmap(
+ csv_result_dir,
+ output_result_dir,
+ "correlation_output",
+ "correlation.pdf",
+ "Correlation",
+ )
+
+
+def plot_reuse_graphs(csv_result_dir, output_result_dir):
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="avg_reuse_interval_naccesses",
+ pdf_name="avg_reuse_interval_naccesses.pdf",
+ xlabel="",
+ ylabel="Percentage of accesses",
+ title="Average reuse interval",
+ vertical=True,
+ x_prefix="< ",
+ )
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="avg_reuse_interval",
+ pdf_name="avg_reuse_interval.pdf",
+ xlabel="",
+ ylabel="Percentage of blocks",
+ title="Average reuse interval",
+ vertical=True,
+ x_prefix="< ",
+ )
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="access_reuse_interval",
+ pdf_name="reuse_interval.pdf",
+ xlabel="Seconds",
+ ylabel="Percentage of accesses",
+ title="Reuse interval",
+ vertical=True,
+ x_prefix="< ",
+ )
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="reuse_lifetime",
+ pdf_name="reuse_lifetime.pdf",
+ xlabel="Seconds",
+ ylabel="Percentage of blocks",
+ title="Reuse lifetime",
+ vertical=True,
+ x_prefix="< ",
+ )
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="reuse_blocks_timeline",
+ pdf_name="reuse_blocks_timeline.pdf",
+ xlabel="",
+ ylabel="Percentage of blocks",
+ title="Reuse blocks timeline",
+ vertical=False,
+ legend=False,
+ )
+
+
+def plot_percentage_access_summary(csv_result_dir, output_result_dir):
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="percentage_of_accesses_summary",
+ pdf_name="percentage_access.pdf",
+ xlabel="",
+ ylabel="Percentage of accesses",
+ title="",
+ vertical=True,
+ x_prefix="",
+ )
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="percent_ref_keys",
+ pdf_name="percent_ref_keys.pdf",
+ xlabel="",
+ ylabel="Percentage of blocks",
+ title="",
+ vertical=True,
+ x_prefix="",
+ )
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="percent_data_size_on_ref_keys",
+ pdf_name="percent_data_size_on_ref_keys.pdf",
+ xlabel="",
+ ylabel="Percentage of blocks",
+ title="",
+ vertical=True,
+ x_prefix="",
+ )
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="percent_accesses_on_ref_keys",
+ pdf_name="percent_accesses_on_ref_keys.pdf",
+ xlabel="",
+ ylabel="Percentage of blocks",
+ title="",
+ vertical=True,
+ x_prefix="",
+ )
+
+
+def plot_access_count_summary(csv_result_dir, output_result_dir):
+ plot_stacked_bar_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_suffix="access_count_summary",
+ pdf_name="access_count_summary.pdf",
+ xlabel="Access count",
+ ylabel="Percentage of blocks",
+ title="",
+ vertical=True,
+ x_prefix="< ",
+ )
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="skewness",
+ pdf_name="skew.pdf",
+ xlabel="",
+ ylabel="Percentage of accesses",
+ title="Skewness",
+ vertical=True,
+ legend=False,
+ )
+
+
+def plot_miss_ratio_timeline(csv_result_dir, output_result_dir):
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="3600_miss_ratio_timeline",
+ pdf_name="miss_ratio_timeline.pdf",
+ xlabel="Time",
+ ylabel="Miss Ratio (%)",
+ title="Miss ratio timeline",
+ vertical=False,
+ legend=True,
+ )
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="3600_miss_timeline",
+ pdf_name="miss_timeline.pdf",
+ xlabel="Time",
+ ylabel="# of misses ",
+ title="Miss timeline",
+ vertical=False,
+ legend=True,
+ )
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="3600_miss_timeline",
+ pdf_name="miss_timeline.pdf",
+ xlabel="Time",
+ ylabel="# of misses ",
+ title="Miss timeline",
+ vertical=False,
+ legend=True,
+ )
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="3600_policy_timeline",
+ pdf_name="policy_timeline.pdf",
+ xlabel="Time",
+ ylabel="# of times a policy is selected ",
+ title="Policy timeline",
+ vertical=False,
+ legend=True,
+ )
+ plot_line_charts(
+ csv_result_dir,
+ output_result_dir,
+ filename_prefix="",
+ filename_suffix="3600_policy_ratio_timeline",
+ pdf_name="policy_ratio_timeline.pdf",
+ xlabel="Time",
+ ylabel="Percentage of times a policy is selected ",
+ title="Policy timeline",
+ vertical=False,
+ legend=True,
+ )
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 3:
+ print(
+ "Must provide two arguments: \n"
+ "1) The directory that saves a list of "
+ "directories which contain block cache trace analyzer result files. \n"
+ "2) the directory to save plotted graphs. \n"
+ )
+ exit(1)
+ csv_result_dir = sys.argv[1]
+ output_result_dir = sys.argv[2]
+ print(
+ "Processing directory {} and save graphs to {}.".format(
+ csv_result_dir, output_result_dir
+ )
+ )
+ for csv_relative_dir in os.listdir(csv_result_dir):
+ csv_abs_dir = csv_result_dir + "/" + csv_relative_dir
+ result_dir = output_result_dir + "/" + csv_relative_dir
+ if not os.path.isdir(csv_abs_dir):
+ print("{} is not a directory".format(csv_abs_dir))
+ continue
+ print("Processing experiment dir: {}".format(csv_relative_dir))
+ if not os.path.exists(result_dir):
+ os.makedirs(result_dir)
+ plot_access_count_summary(csv_abs_dir, result_dir)
+ plot_timeline(csv_abs_dir, result_dir)
+ plot_miss_ratio_timeline(csv_result_dir, output_result_dir)
+ plot_correlation(csv_abs_dir, result_dir)
+ plot_reuse_graphs(csv_abs_dir, result_dir)
+ plot_percentage_access_summary(csv_abs_dir, result_dir)
+ plot_miss_stats_graphs(
+ csv_abs_dir,
+ result_dir,
+ file_prefix="",
+ file_suffix="mrc",
+ ylabel="Miss ratio (%)",
+ pdf_file_name="mrc",
+ )
+ plot_miss_stats_diff_lru_graphs(
+ csv_abs_dir,
+ result_dir,
+ file_prefix="",
+ file_suffix="mrc",
+ ylabel="Miss ratio (%)",
+ pdf_file_name="mrc_diff_lru",
+ )
+ # The following stats are only available in pysim.
+ for time_unit in ["1", "60", "3600"]:
+ plot_miss_stats_graphs(
+ csv_abs_dir,
+ result_dir,
+ file_prefix="ml_{}_".format(time_unit),
+ file_suffix="p95mb",
+ ylabel="p95 number of byte miss per {} seconds".format(time_unit),
+ pdf_file_name="p95mb_per{}_seconds".format(time_unit),
+ )
+ plot_miss_stats_graphs(
+ csv_abs_dir,
+ result_dir,
+ file_prefix="ml_{}_".format(time_unit),
+ file_suffix="avgmb",
+ ylabel="Average number of byte miss per {} seconds".format(time_unit),
+ pdf_file_name="avgmb_per{}_seconds".format(time_unit),
+ )
+ plot_miss_stats_diff_lru_graphs(
+ csv_abs_dir,
+ result_dir,
+ file_prefix="ml_{}_".format(time_unit),
+ file_suffix="p95mb",
+ ylabel="p95 number of byte miss per {} seconds".format(time_unit),
+ pdf_file_name="p95mb_per{}_seconds_diff_lru".format(time_unit),
+ )
+ plot_miss_stats_diff_lru_graphs(
+ csv_abs_dir,
+ result_dir,
+ file_prefix="ml_{}_".format(time_unit),
+ file_suffix="avgmb",
+ ylabel="Average number of byte miss per {} seconds".format(time_unit),
+ pdf_file_name="avgmb_per{}_seconds_diff_lru".format(time_unit),
+ )