-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplot.py
More file actions
163 lines (142 loc) · 6.5 KB
/
plot.py
File metadata and controls
163 lines (142 loc) · 6.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import csv
import sys
import matplotlib
matplotlib.use('Agg')# no display needed — saves to file
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from collections import defaultdict
#Color per policy
COLOR = {
'FIFO' : '#4C72B0', # blue
'LRU' : '#55A868', # green
'Random' : '#C44E52', # red
'Belady' : '#8172B2', # purple ← optimal upper bound
'SA-LRU' : '#DD8452', # orange ← our proposed policy
}
ORDER = ['FIFO', 'LRU', 'Random', 'Belady', 'SA-LRU']
# Read results_fixed.csv
def read_fixed(path='results_fixed.csv'):
"""
Returns { policy -> { hit_rate: %, miss_rate: % } }
"""
data = {}
try:
with open(path) as f:
for row in csv.DictReader(f):
data[row['policy']] = {
'hit_rate' : float(row['hit_rate']) * 100,
'miss_rate': float(row['miss_rate']) * 100,
}
except FileNotFoundError:
print(f"ERROR: {path} not found. Run ./cache_sim first.")
sys.exit(1)
return data
# ── Read results.csv (cache size sweep) ──────────────────────
def read_sweep(path='results.csv'):
"""
Returns { policy -> { cache_kb -> hit_rate% } }
"""
data = defaultdict(dict)
try:
with open(path) as f:
for row in csv.DictReader(f):
data[row['policy']][int(row['cache_kb'])] = float(row['hit_rate']) * 100
except FileNotFoundError:
print(f"ERROR: {path} not found. Run ./cache_sim first.")
sys.exit(1)
return data
# Plotting
def plot(fixed, sweep, out='cs204_results.png'):
fig, axes = plt.subplots(2, 2, figsize=(14, 9))
fig.suptitle('CS204 — Cache Replacement Policy Analysis',
fontsize=14, fontweight='bold', y=1.01)
plt.tight_layout(pad=3.5)
policies = [p for p in ORDER if p in fixed]
hit_rates = [fixed[p]['hit_rate'] for p in policies]
miss_rates = [fixed[p]['miss_rate'] for p in policies]
colors = [COLOR[p] for p in policies]
belady_hr = fixed.get('Belady', {}).get('hit_rate', 0)
#Graph 1: Hit Rate Bar
ax = axes[0][0]
bars = ax.bar(policies, hit_rates, color=colors, edgecolor='white',
linewidth=0.8, width=0.55)
ax.set_title('Hit Rate by Policy\n(4 KB cache, 64 B block, 4-way)', fontsize=11)
ax.set_ylabel('Hit Rate (%)')
ax.set_ylim(max(0, min(hit_rates) - 5), 100)
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=100))
for bar, val in zip(bars, hit_rates):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.2,
f'{val:.2f}%', ha='center', va='bottom', fontsize=8)
if belady_hr:
ax.axhline(y=belady_hr, color=COLOR['Belady'], linestyle='--',
linewidth=1.3, label=f'Belady bound ({belady_hr:.2f}%)')
ax.legend(fontsize=8)
# ── Graph 2: Miss Rate Bar ────────────────────────────
ax = axes[0][1]
bars = ax.bar(policies, miss_rates, color=colors, edgecolor='white',
linewidth=0.8, width=0.55)
ax.set_title('Miss Rate by Policy', fontsize=11)
ax.set_ylabel('Miss Rate (%)')
ax.set_ylim(0, max(miss_rates) * 1.35 if miss_rates else 30)
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=100))
for bar, val in zip(bars, miss_rates):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.05,
f'{val:.2f}%', ha='center', va='bottom', fontsize=8)
# Graph 3: Hit Rate vs Cache Size
ax = axes[1][0]
cache_sizes = sorted(next(iter(sweep.values())).keys()) if sweep else []
for pol in ORDER:
if pol not in sweep: continue
vals = [sweep[pol].get(sz, 0) for sz in cache_sizes]
ax.plot(cache_sizes, vals, marker='o', label=pol,
color=COLOR[pol],
linewidth=2.0 if pol in ('Belady', 'SA-LRU') else 1.3,
linestyle='--' if pol == 'Belady' else '-',
zorder=3 if pol in ('Belady', 'SA-LRU') else 2)
ax.set_title('Hit Rate vs Cache Size', fontsize=11)
ax.set_xlabel('Cache Size (KB)')
ax.set_ylabel('Hit Rate (%)')
ax.set_xticks(cache_sizes)
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=100))
ax.legend(fontsize=8, loc='lower right')
ax.grid(True, linestyle=':', alpha=0.5)
#Graph 4: SA-LRU vs LRU vs Belady
ax = axes[1][1]
if all(p in sweep for p in ('LRU', 'SA-LRU', 'Belady')):
lru_v = [sweep['LRU'].get(sz, 0) for sz in cache_sizes]
salru_v = [sweep['SA-LRU'].get(sz, 0) for sz in cache_sizes]
bel_v = [sweep['Belady'].get(sz, 0) for sz in cache_sizes]
ax.plot(cache_sizes, lru_v, marker='s', label='LRU',
color=COLOR['LRU'], linewidth=2)
ax.plot(cache_sizes, salru_v, marker='D', label='SA-LRU (proposed)',
color=COLOR['SA-LRU'], linewidth=2)
ax.plot(cache_sizes, bel_v, marker='^', label='Belady (optimal)',
color=COLOR['Belady'], linewidth=1.5, linestyle='--')
ax.fill_between(cache_sizes, lru_v, salru_v,
alpha=0.18, color=COLOR['SA-LRU'], label='SA-LRU gain')
ax.set_title('SA-LRU vs LRU vs Belady\n(proposed policy focus)', fontsize=11)
ax.set_xlabel('Cache Size (KB)')
ax.set_ylabel('Hit Rate (%)')
ax.set_xticks(cache_sizes)
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=100))
ax.legend(fontsize=8)
ax.grid(True, linestyle=':', alpha=0.5)
plt.savefig(out, dpi=150, bbox_inches='tight')
print(f"Graph saved → {out}")
plt.close()
#Main
if __name__ == '__main__':
print("Reading simulator output...")
fixed = read_fixed('results_fixed.csv')
sweep = read_sweep('results.csv')
belady_hr = fixed.get('Belady', {}).get('hit_rate', 0)
print(f"\n{'Policy':<10} {'Hit%':>8} {'Miss%':>8} vs Belady")
print("-" * 42)
for p in ORDER:
if p not in fixed: continue
gap = fixed[p]['hit_rate'] - belady_hr
print(f"{p:<10} {fixed[p]['hit_rate']:>7.2f}% {fixed[p]['miss_rate']:>7.2f}% {gap:+.2f}%")
if 'SA-LRU' in fixed and 'LRU' in fixed:
delta = fixed['SA-LRU']['hit_rate'] - fixed['LRU']['hit_rate']
print(f"\nSA-LRU improvement over LRU: {delta:+.2f}%")
plot(fixed, sweep)