diff --git a/tasks/plaksina-av/lab_5/README.md b/tasks/plaksina-av/lab_5/README.md new file mode 100644 index 0000000..e12632a --- /dev/null +++ b/tasks/plaksina-av/lab_5/README.md @@ -0,0 +1,100 @@ +# Отчет по лабораторной работе №5 + +Выполнила студентка гр. ИСЭбд-41 Плаксина А.В. + +# Описание работы приложения + +Приложение реализовнао на языке питон, использована среда PyCharm для разработки. +Было развернуто два приложения: +1. Веб приложение для умножения матриц +2. Консольное приложение для бенчмаркинга + +Последовательно запускаем две программы: сначала simple_app.py, затем benchmark.py. +Веб - приложение позволяет указать размеры матрицы и используемый алгоритм, и на основании этого получить результат перемножения матриц в интерактивном режиме + +Развернули два приложения + +1. Приложение 1 - веб приложение для умножения матриц +2. Приложение 2 - консольное приложение для сравнения эффективности работы алгоритмов. + +Первое приложение дает нам возможность умножить матрицы, получить результат в интерактивном режиме +с указанием используемого алгоритма и с указанием размера матрицы. + +При запуске веб приложения с выбором последовательного умножения: + +![](photo/ph23.jpg) + +Результат последовательного умножения: + +![](photo/ph24.jpg) + +Код реализующий последовательное умножение матриц: + +```cs +def multiply_matrices(matrix_a, matrix_b): + if len(matrix_a[0]) != len(matrix_b): + raise ValueError("матрицы имеют разную длину") + + result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))] + + for i in range(len(matrix_a)): + for j in range(len(matrix_b[0])): + for k in range(len(matrix_b)): + result[i][j] += matrix_a[i][k] * matrix_b[k][j] + + return result +``` + +При запуске веб приложения с выбором параллельного умножения: + +![](photo/ph25.jpg) + +Результат параллельного умножения: + +![](photo/ph26.jpg) + +Код реализующий параллельное умножение матриц: + +```cs +def multiply_matrices_parallel(matrix_a, matrix_b, threads): + if len(matrix_a[0]) != len(matrix_b): + raise ValueError("матрицы имеют разную длину") + + result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))] + + with multiprocessing.Pool(processes=threads) as pool: + args_list = [(matrix_a, matrix_b, i) for i in range(len(matrix_a))] + rows_results = pool.map(multiply_row, args_list) + + for row_result, row_index in rows_results: + result[row_index] = row_result + + return result + +``` +# Бенчмаркинг + +Для сравнения времени работы двух алгоритмов умножения, проведем несколько бенчмарков + +Для матриц размерностью 100x100, 300x300, 500x500, для параллельного алгоритма дополнительно для каждого введенного количества потоков (4, 16, 32) + +Результаты бенчмаркинга для последовательного способа матриц различной размерности: + +![](photo/ph27.jpg) + +Результаты бенчмаркинга для параллельного способа матриц различной размерности с количеством потоков равном 4: + +![](photo/ph28.jpg) + +Результаты бенчмаркинга для параллельного способа матриц различной размерности с количеством потоков равном 16: + +![](photo/ph29.jpg) + +Результаты бенчмаркинга для параллельного способа матриц различной размерности с количеством потоков равном 32: + +![](photo/ph30.jpg) + +# Вывод + +С использованием параллельного алгоритма скорость обработки существенно увеличивается, особенно при большой размерности матрицы. +В данном примере оптимальная скорость достигается при количестве потоков равном 16. \ No newline at end of file diff --git a/tasks/plaksina-av/lab_5/benchmarking.py b/tasks/plaksina-av/lab_5/benchmarking.py new file mode 100644 index 0000000..835cc24 --- /dev/null +++ b/tasks/plaksina-av/lab_5/benchmarking.py @@ -0,0 +1,82 @@ +import multiprocessing + +import numpy as np +import time + + +def multiply_matrices(matrix_a, matrix_b): + if len(matrix_a[0]) != len(matrix_b): + raise ValueError("матрицы имеют разную длину") + + result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))] + + for i in range(len(matrix_a)): + for j in range(len(matrix_b[0])): + for k in range(len(matrix_b)): + result[i][j] += matrix_a[i][k] * matrix_b[k][j] + + return result + + +def multiply_row(args): + matrix_a, matrix_b, i = args + row_result = [0 for _ in range(len(matrix_b[0]))] + for j in range(len(matrix_b[0])): + for k in range(len(matrix_b)): + row_result[j] += matrix_a[i][k] * matrix_b[k][j] + return row_result, i + + +def multiply_matrices_parallel(matrix_a, matrix_b, threads): + if len(matrix_a[0]) != len(matrix_b): + raise ValueError("матрицы имеют разную длину") + + result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))] + + with multiprocessing.Pool(processes=threads) as pool: + args_list = [(matrix_a, matrix_b, i) for i in range(len(matrix_a))] + rows_results = pool.map(multiply_row, args_list) + + for row_result, row_index in rows_results: + result[row_index] = row_result + + return result + + +def benchmark_sequential(size): + matrix_a = np.random.rand(size, size) + matrix_b = np.random.rand(size, size) + + start_time = time.time() + multiply_matrices(matrix_a, matrix_b) + end_time = time.time() + + return end_time - start_time + + +def benchmark_parallel(size, num_threads): + matrix_a = np.random.rand(size, size) + matrix_b = np.random.rand(size, size) + + start_time = time.time() + multiply_matrices_parallel(matrix_a, matrix_b, num_threads) + end_time = time.time() + + return end_time - start_time + + +if __name__ == "__main__": + sizes = [100, 300, 500] + threads = [4, 16, 32] + + for size in sizes: + sequential_time = benchmark_sequential(size) + print(f"Время для последовательного способа: {sequential_time} с") + print(f"Размер матрицы: {size}x{size}") + + for thread in threads: + for size in sizes: + parallel_time = benchmark_parallel(size, thread) + print(f"Размер матрицы: {size}x{size}") + print(f"Время для параллельного спобсоба: {parallel_time} с") + print(f"Потоков: {thread}") \ No newline at end of file diff --git a/tasks/plaksina-av/lab_5/photo/ph23.jpg b/tasks/plaksina-av/lab_5/photo/ph23.jpg new file mode 100644 index 0000000..245a1b4 Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph23.jpg differ diff --git a/tasks/plaksina-av/lab_5/photo/ph24.jpg b/tasks/plaksina-av/lab_5/photo/ph24.jpg new file mode 100644 index 0000000..cb9d846 Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph24.jpg differ diff --git a/tasks/plaksina-av/lab_5/photo/ph25.jpg b/tasks/plaksina-av/lab_5/photo/ph25.jpg new file mode 100644 index 0000000..294fc49 Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph25.jpg differ diff --git a/tasks/plaksina-av/lab_5/photo/ph26.jpg b/tasks/plaksina-av/lab_5/photo/ph26.jpg new file mode 100644 index 0000000..cfc6d23 Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph26.jpg differ diff --git a/tasks/plaksina-av/lab_5/photo/ph27.jpg b/tasks/plaksina-av/lab_5/photo/ph27.jpg new file mode 100644 index 0000000..bde4ea3 Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph27.jpg differ diff --git a/tasks/plaksina-av/lab_5/photo/ph28.jpg b/tasks/plaksina-av/lab_5/photo/ph28.jpg new file mode 100644 index 0000000..4bd9f7b Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph28.jpg differ diff --git a/tasks/plaksina-av/lab_5/photo/ph29.jpg b/tasks/plaksina-av/lab_5/photo/ph29.jpg new file mode 100644 index 0000000..70fafa6 Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph29.jpg differ diff --git a/tasks/plaksina-av/lab_5/photo/ph30.jpg b/tasks/plaksina-av/lab_5/photo/ph30.jpg new file mode 100644 index 0000000..e0b9300 Binary files /dev/null and b/tasks/plaksina-av/lab_5/photo/ph30.jpg differ diff --git a/tasks/plaksina-av/lab_5/templates/index.html b/tasks/plaksina-av/lab_5/templates/index.html new file mode 100644 index 0000000..3918598 --- /dev/null +++ b/tasks/plaksina-av/lab_5/templates/index.html @@ -0,0 +1,24 @@ + + + + + + + Умножение матриц + + +

Умножение матриц

+
+ +
+ + +
+ + +
+ + \ No newline at end of file diff --git a/tasks/plaksina-av/lab_5/templates/result.html b/tasks/plaksina-av/lab_5/templates/result.html new file mode 100644 index 0000000..0c7a64f --- /dev/null +++ b/tasks/plaksina-av/lab_5/templates/result.html @@ -0,0 +1,19 @@ + + + + + + + Результат + + +

Результат

+

Матрица A:

+
{{ matrix_a }}
+

Матрица B:

+
{{ matrix_b }}
+

Результат:

+
{{ result }}
+ Назад + + \ No newline at end of file diff --git a/tasks/plaksina-av/lab_5/web.py b/tasks/plaksina-av/lab_5/web.py new file mode 100644 index 0000000..37f6638 --- /dev/null +++ b/tasks/plaksina-av/lab_5/web.py @@ -0,0 +1,73 @@ +import multiprocessing + +from flask import Flask, render_template, request +import numpy as np +import concurrent.futures + +app = Flask(__name__) + + +def multiply_matrices(matrix_a, matrix_b): + if len(matrix_a[0]) != len(matrix_b): + raise ValueError("матрицы имеют разную длину") + + result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))] + + for i in range(len(matrix_a)): + for j in range(len(matrix_b[0])): + for k in range(len(matrix_b)): + result[i][j] += matrix_a[i][k] * matrix_b[k][j] + + return result + + +def multiply_row(args): + matrix_a, matrix_b, i = args + row_result = [0 for _ in range(len(matrix_b[0]))] + for j in range(len(matrix_b[0])): + for k in range(len(matrix_b)): + row_result[j] += matrix_a[i][k] * matrix_b[k][j] + return row_result, i + + +def multiply_matrices_parallel(matrix_a, matrix_b, threads): + if len(matrix_a[0]) != len(matrix_b): + raise ValueError("матрицы имеют разную длину") + + result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))] + + with multiprocessing.Pool(processes=threads) as pool: + args_list = [(matrix_a, matrix_b, i) for i in range(len(matrix_a))] + rows_results = pool.map(multiply_row, args_list) + + for row_result, row_index in rows_results: + result[row_index] = row_result + + return result + + +@app.route('/') +def index(): + return render_template('index.html') + + +@app.route('/multiply', methods=['POST']) +def multiply(): + n = int(request.form.get('matrix_a')) + matrix_a = np.random.randint(10, size=(n, n)) + matrix_b = np.random.randint(10, size=(n, n)) + + operation_type = request.form.get('operation_type') + + if operation_type == 'sequential': + result = multiply_matrices(matrix_a, matrix_b) + elif operation_type == 'parallel': + result = multiply_matrices_parallel(matrix_a, matrix_b, 16) + else: + return "Invalid operation type" + + return render_template('result.html', matrix_a=matrix_a, matrix_b=matrix_b, result=result) + + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file