This repository was archived by the owner on Oct 3, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsim_matrix.py
More file actions
executable file
·106 lines (88 loc) · 3.88 KB
/
sim_matrix.py
File metadata and controls
executable file
·106 lines (88 loc) · 3.88 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
#!/usr/bin/env python3
from functools import reduce
from operator import getitem
from time import process_time
from typing import Any, Generator
from src import VMSimBase, VMSimClock, VMSimLRU, VMSimOpt, VMSimRand
def sim_matrix(
trace_file: str,
frame_sizes: list[int] = [8, 16, 32, 64],
algorithms: list[VMSimBase] = [VMSimOpt, VMSimClock, VMSimLRU, VMSimRand],
verbose: bool = False,
) -> Generator[dict[str, Any], None, None]:
"""Run a matrix of tests with different algorithms and frame sizes
Args:
trace_file (str): Path to the trace file
frame_sizes (list[int], optional): List of frame sizes to test. Defaults to [8, 16, 32, 64].
algorithms (list[VMSimBase], optional): List of algorithms to test. Defaults to [VMSimOpt, VMSimClock, VMSimLRU, VMSimRand].
verbose (bool, optional): Whether to print verbose output. Defaults to False.
Yields:
Generator[dict, None, None]: Results of the simulation
"""
# Initialize the simulators for each algorithm and frame size
sim_matrix: list[VMSimBase] = [
VMSim(num_frames) for VMSim in algorithms for num_frames in frame_sizes
]
for vmsim in sim_matrix:
start_time = process_time()
res = vmsim.sim(trace_file, verbose=verbose)
end_time = process_time()
res["time"] = end_time - start_time
yield res
def avg_result(results: list[dict[str, Any]], key: str) -> float:
"""Calculate the average of a key in a list of dictionaries. Works with nested keys too
Args:
results (list[dict]): List of dictionaries
key (str): Key to average values from
Returns:
float: Average result
Sources:
https://stackoverflow.com/a/20324938
"""
return sum(reduce(getitem, key.split("."), r) for r in results) / len(results)
if __name__ == "__main__":
# Results table headers
print(
"| Algorithm | Frames | Memory Accesses | Page Faults | Disk Writes | Leaves | Table Size (bytes) | Time (s) |\n"
"| --------- | ------ | --------------- | ----------- | ----------- | ------ | ------------------ | -------- |"
)
for res in sim_matrix(
"trace/cc.trace",
frame_sizes=[8, 16, 32, 64],
algorithms=[VMSimOpt, VMSimClock, VMSimLRU],
verbose=False,
):
# Outputs in markdown format
print(
f"| {res['algorithm']:9} "
f"| {res['num_frames']:<6d} "
f"| {res['stats']['mem_accesses']:<15d} "
f"| {res['stats']['total_page_faults']:<11d} "
f"| {res['stats']['dirty_evict_page_faults']:<11d} "
f"| {res['page_table']['num_leaves']:<6d} "
f"| {res['page_table']['total_size']:<18d} " # Will differ on 32/64 bit systems
f"| {res['time']:<8.4f} "
f"|"
)
# Since the random algoirhm is non-deterministic, we need to run it multiple times and average the results
for frame_size in [8, 16, 32, 64]:
merged_res = []
for res in sim_matrix(
"trace/cc.trace",
frame_sizes=[frame_size] * 5, # Runs the same frame size 5 times
algorithms=[VMSimRand],
verbose=False,
):
merged_res.append(res)
# We'll be printing the average results of the 5 runs for the current frame size
print(
f"| {VMSimRand.ALGORITHM:9} "
f"| {frame_size:<6d} "
f"| {avg_result(merged_res, 'stats.mem_accesses'):<15.0f} "
f"| {avg_result(merged_res, 'stats.total_page_faults'):<11.0f} "
f"| {avg_result(merged_res, 'stats.dirty_evict_page_faults'):<11.0f} "
f"| {avg_result(merged_res, 'page_table.num_leaves'):<6.0f} " # Rounded down
f"| {avg_result(merged_res, 'page_table.total_size'):<18.0f} " # Rounded down
f"| {avg_result(merged_res, 'time'):<8.4f} "
f"|"
)