|
#!/usr/bin/env python3 |
|
import csv |
|
import sys |
|
from collections import defaultdict |
|
|
|
def main(): |
|
results_file = sys.argv[1] if len(sys.argv) > 1 else "results.csv" |
|
|
|
import matplotlib |
|
matplotlib.use("Agg") |
|
import matplotlib.pyplot as plt |
|
import matplotlib.ticker as ticker |
|
|
|
data = defaultdict(lambda: ([], [], [])) |
|
with open(results_file) as f: |
|
reader = csv.DictReader(f) |
|
for row in reader: |
|
ns = int(row["node_size"]) |
|
ws = int(row["working_set"]) |
|
latency = float(row["ns_per_chase"]) |
|
num_monsters = ws // ns |
|
data[ns][0].append(num_monsters) |
|
data[ns][1].append(latency) |
|
data[ns][2].append(ws) |
|
|
|
colors = {64: "#e74c3c", 128: "#3498db", 256: "#2ecc71", 512: "#9b59b6"} |
|
|
|
def fmt_count(x, pos): |
|
if x >= 1_000_000: |
|
return f"{x/1_000_000:.0f}M" |
|
if x >= 1_000: |
|
return f"{x/1_000:.0f}K" |
|
return f"{x:.0f}" |
|
|
|
fig, (ax_top, ax_bot) = plt.subplots(2, 1, figsize=(12, 10), sharex=True, |
|
gridspec_kw={"height_ratios": [1, 1.2]}) |
|
|
|
# --- Top: zoomed into L1/L2/L3 region (0-60 ns) --- |
|
for ns in sorted(data.keys()): |
|
monsters, latencies, _ = data[ns] |
|
label = f"{ns}B Monster" |
|
ax_top.plot(monsters, latencies, "o-", label=label, |
|
color=colors.get(ns, None), linewidth=2, markersize=5) |
|
|
|
ax_top.set_ylim(0, 60) |
|
ax_top.set_ylabel("Latency (ns / lookup)", fontsize=12) |
|
ax_top.set_title("Random Access Latency vs Number of Monsters", |
|
fontsize=14) |
|
ax_top.legend(fontsize=10, loc="upper left") |
|
ax_top.grid(True, alpha=0.3) |
|
ax_top.text(0.98, 0.95, "Zoomed in", transform=ax_top.transAxes, |
|
ha="right", va="top", fontsize=10, fontstyle="italic", color="black") |
|
|
|
# --- Bottom: full range showing DRAM cliff --- |
|
for ns in sorted(data.keys()): |
|
monsters, latencies, _ = data[ns] |
|
label = f"{ns}B Monster" |
|
ax_bot.plot(monsters, latencies, "o-", label=label, |
|
color=colors.get(ns, None), linewidth=2, markersize=5) |
|
|
|
ax_bot.set_ylabel("Latency (ns / lookup)", fontsize=12) |
|
ax_bot.set_xlabel("Number of Monsters", fontsize=12) |
|
ax_bot.grid(True, alpha=0.3) |
|
|
|
ax_bot.set_xscale("log", base=2) |
|
ax_bot.xaxis.set_major_formatter(ticker.FuncFormatter(fmt_count)) |
|
|
|
plt.tight_layout() |
|
plt.savefig("cache_staircase.png", dpi=150) |
|
print("Saved cache_staircase.png") |
|
|
|
if __name__ == "__main__": |
|
main() |