-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpu_pinned_Core_0.py
143 lines (111 loc) · 4.92 KB
/
cpu_pinned_Core_0.py
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
import os
import time
import random
import pandas as pd
from statistics import mean, stdev
# Pin the process to CPU core 0
os.system("taskset -p 0x1 %d" % os.getpid())
def split_matrix(matrix):
# Split the matrix into 4 submatrices
rows, cols = len(matrix), len(matrix[0])
split_row, split_col = rows // 2, cols // 2
A11 = [row[:split_col] for row in matrix[:split_row]]
A12 = [row[split_col:] for row in matrix[:split_row]]
A21 = [row[:split_col] for row in matrix[split_row:]]
A22 = [row[split_col:] for row in matrix[split_row:]]
return A11, A12, A21, A22
def add_matrices(matrix1, matrix2):
# Add two matrices element-wise
return [
[matrix1[i][j] + matrix2[i][j] for j in range(len(matrix1[0]))]
for i in range(len(matrix1))
]
def subtract_matrices(matrix1, matrix2):
# Subtract matrix2 from matrix1 element-wise
return [
[matrix1[i][j] - matrix2[i][j] for j in range(len(matrix1[0]))]
for i in range(len(matrix1))
]
def strassen(matrix1, matrix2):
# Recursive implementation of Strassen's algorithm
if len(matrix1) == 1:
return [[matrix1[0][0] * matrix2[0][0]]]
A11, A12, A21, A22 = split_matrix(matrix1)
B11, B12, B21, B22 = split_matrix(matrix2)
P1 = strassen(A11, subtract_matrices(B12, B22))
P2 = strassen(add_matrices(A11, A12), B22)
P3 = strassen(add_matrices(A21, A22), B11)
P4 = strassen(A22, subtract_matrices(B21, B11))
P5 = strassen(add_matrices(A11, A22), add_matrices(B11, B22))
P6 = strassen(subtract_matrices(A12, A22), add_matrices(B21, B22))
P7 = strassen(subtract_matrices(A11, A21), add_matrices(B11, B12))
C11 = subtract_matrices(add_matrices(P5, P4), subtract_matrices(P2, P6))
C12 = add_matrices(P1, P2)
C21 = add_matrices(P3, P4)
C22 = subtract_matrices(subtract_matrices(P5, P3), subtract_matrices(P1, P7))
result = [
C11[i] + C12[i]
for i in range(len(C11))
] + [
C21[i] + C22[i]
for i in range(len(C21))
]
return result
def generate_random_matrix(rows, cols, seed=None):
# Generate a random matrix with specified dimensions
if seed is not None:
random.seed(seed)
return [[random.randint(1, 100) for _ in range(cols)] for _ in range(rows)]
def benchmark(matrix_size, repetitions=5, warm_up_runs=3, stress_runs=100, seed=None):
data = {'Matrix Size': [], 'Run Number': [], 'Runtime (seconds)': []}
# Warm-up phase
for _ in range(warm_up_runs):
matrix1 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
matrix2 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
strassen(matrix1, matrix2)
# Actual benchmarking
for run_number in range(1, repetitions + 1):
matrix1 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
matrix2 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
start_time = time.perf_counter()
strassen(matrix1, matrix2)
end_time = time.perf_counter()
runtime = end_time - start_time
data['Matrix Size'].append(matrix_size)
data['Run Number'].append(run_number)
data['Runtime (seconds)'].append(runtime)
df = pd.DataFrame(data)
average_runtimes = df.groupby('Matrix Size')['Runtime (seconds)'].agg([mean, stdev]).reset_index()
print("\nAverage Runtimes:\n", average_runtimes)
# Stress testing
stress_data = []
for _ in range(stress_runs):
matrix1 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
matrix2 = generate_random_matrix(matrix_size, matrix_size, seed=seed)
start_time = time.perf_counter()
strassen(matrix1, matrix2)
end_time = time.perf_counter()
runtime = end_time - start_time
stress_data.append(runtime)
print(f"\nStress Testing for Matrix Size {matrix_size}x{matrix_size}:")
print(f"Mean Runtime: {mean(stress_data)} seconds")
print(f"Standard Deviation: {stdev(stress_data)} seconds")
return df
def multiple_independent_runs(matrix_size, independent_runs=5, repetitions=5, warm_up_runs=3, stress_runs=100, seed=None):
all_data = pd.DataFrame()
for run in range(independent_runs):
print(f"\nIndependent Run {run + 1}/{independent_runs}")
run_data = benchmark(matrix_size, repetitions=repetitions, warm_up_runs=warm_up_runs, stress_runs=stress_runs, seed=seed)
all_data = pd.concat([all_data, run_data], ignore_index=True)
return all_data
# Collect benchmark data
matrix_sizes = [2, 4, 8, 16, 32, 64, 128]
independent_runs = 3
repetitions = 5
stress_runs = 100
final_data = pd.DataFrame()
for matrix_size in matrix_sizes:
matrix_data = multiple_independent_runs(matrix_size, independent_runs=independent_runs, repetitions=repetitions, stress_runs=stress_runs)
final_data = pd.concat([final_data, matrix_data], ignore_index=True)
# Display the combined data table
print("\nCombined Data Table:\n", final_data)