-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathqueue_capacity.py
More file actions
167 lines (139 loc) · 5.71 KB
/
queue_capacity.py
File metadata and controls
167 lines (139 loc) · 5.71 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
164
165
166
167
import subprocess
import re
import matplotlib.pyplot as plt
import time
from datetime import datetime
def get_time_taken_for_tests(cargo_args):
"""Run the server with given args and benchmark it"""
print(f"Starting server with args: {cargo_args}")
# Start server with output suppressed
server_process = subprocess.Popen(
f"./target/debug/server {cargo_args}",
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
# Wait for server to start
time.sleep(2)
try:
# Run benchmark
print("Running benchmark...")
total = 0
for i in range(3):
result = subprocess.run(
"ab -n 10000 -c 10 -s 30 http://localhost:7878/",
shell=True,
capture_output=True,
text=True
)
if result.returncode != 0:
print(f"Benchmark failed with return code {result.returncode}")
print(f"Error: {result.stderr}")
return None
# Extract time taken
match = re.search(r"Time taken for tests:\s*([0-9]*\.?[0-9]+) seconds", result.stdout)
if match:
time_taken = float(match.group(1))
print(f"Extracted time: {time_taken} seconds")
# return time_taken
total += time_taken
else:
print("Could not extract time from output. Output excerpt:")
print(result.stdout[:500])
return None
return total / 3 # Return average time taken
finally:
# Always terminate the server
print("Terminating server...")
server_process.terminate()
try:
server_process.wait(timeout=5)
except subprocess.TimeoutExpired:
print("Server didn't terminate gracefully, forcing...")
server_process.kill()
def main():
# Warm up phase
print("\n=== Warming up ===")
warm_up_time = get_time_taken_for_tests("1")
if warm_up_time:
print(f"Warm-up completed in {warm_up_time} seconds")
# Get sequential time
print("\n=== Getting sequential time ===")
sequential_time = get_time_taken_for_tests("1")
if not sequential_time:
print("Error: Could not determine sequential time. Exiting.")
return
print(f"Sequential time: {sequential_time} seconds")
# Internal capacity values to test
internal_capacities = [1, 2, 4, 8, 16, 32, 64]
parallel_times = []
speedups = []
# Test each capacity
for capacity in internal_capacities:
print(f"\n=== Testing internal capacity: {capacity} ===")
parallel_time = get_time_taken_for_tests(f"2 -q {capacity}")
if not parallel_time:
print(f"Warning: Could not get valid time for capacity {capacity}")
parallel_times.append(None)
speedups.append(None)
continue
parallel_times.append(parallel_time)
# Calculate and store speedup
speedup = sequential_time / parallel_time
speedups.append(speedup)
print(f"Capacity {capacity}: Parallel time = {parallel_time:.3f}s, Speedup = {speedup:.3f}x")
# Filter out None values for plotting
valid_data = [(cap, spd) for cap, spd in zip(internal_capacities, speedups) if spd is not None]
if not valid_data:
print("Error: No valid data points to plot")
return
valid_capacities, valid_speedups = zip(*valid_data)
# Plotting
plt.figure(figsize=(10, 6))
plt.plot(valid_capacities, valid_speedups, marker='o', linestyle='-', linewidth=2)
plt.title('Speedup vs Queue Internal Capacity', fontsize=16)
plt.xlabel('Queue Internal Capacity', fontsize=14)
plt.ylabel('Speedup (Sequential / Parallel)', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.7)
plt.xticks(valid_capacities) # Set x-ticks to match our capacity values
# Add annotations for each point
for i, (cap, spd) in enumerate(zip(valid_capacities, valid_speedups)):
plt.annotate(f"{spd:.2f}x",
(cap, spd),
textcoords="offset points",
xytext=(0, 10),
ha='center')
# Get current timestamp
now = datetime.now()
timestamp = now.strftime("%Y-%m-%d_%H-%M-%S")
# Create a unique filename with timestamp
filename = f"speedup_plot_{timestamp}.png"
# Save the plot with high resolution
plt.savefig(filename, dpi=300, bbox_inches='tight')
print(f"\nPlot saved as: {filename}")
# Save data to CSV
csv_filename = f"speedup_data_{timestamp}.csv"
with open(csv_filename, "w") as f:
f.write("Capacity,ParallelTime,Speedup\n")
for cap, pt, spd in zip(internal_capacities, parallel_times, speedups):
if pt is not None and spd is not None:
f.write(f"{cap},{pt},{spd}\n")
print(f"Data saved to: {csv_filename}")
# Show summary of results
print("\n=== Results Summary ===")
print(f"Sequential time: {sequential_time:.3f} seconds")
print("Queue Capacity | Parallel Time | Speedup")
print("-------------- | ------------- | -------")
for cap, ptime, spd in zip(internal_capacities, parallel_times, speedups):
if ptime and spd:
print(f"{cap:14d} | {ptime:13.3f}s | {spd:7.3f}x")
else:
print(f"{cap:14d} | {'N/A':13s} | {'N/A':7s}")
# Try to show the plot
try:
plt.show()
except Exception as e:
print(f"Could not display plot: {e}")
print(f"Plot has been saved to {filename}")
if __name__ == '__main__':
main()