diff --git a/volkov_rafael_lab_5/README.md b/volkov_rafael_lab_5/README.md new file mode 100644 index 0000000..9cb33a6 --- /dev/null +++ b/volkov_rafael_lab_5/README.md @@ -0,0 +1,30 @@ +# Лабораторная работа №5 + +Задание: + +Требуется сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности. + +Сделать несколько бенчмарков последовательного и параллельного алгоритма на умножение двух матриц размером 100x100, 300x300, 500x500 элементов. + +

+

Код программы
+ +

+

+

Код программы
+ +

+

+

Код программы
+ +

+

+

Результат программы
+ +

+ +Вывод: Параллельный алгоритм не сильно ускорил работу программы, его стоит использовить при матрице большего размера например 10000х10000 + +# Видео + +Видео с разбором лабораторной работы - [Видео](https://drive.google.com/file/d/1QazsGcupE0TkhUA3QUuc6_hL2K-p579R/view?usp=sharing) diff --git a/volkov_rafael_lab_5/screens/img1.png b/volkov_rafael_lab_5/screens/img1.png new file mode 100644 index 0000000..6d817e1 Binary files /dev/null and b/volkov_rafael_lab_5/screens/img1.png differ diff --git a/volkov_rafael_lab_5/screens/img2.png b/volkov_rafael_lab_5/screens/img2.png new file mode 100644 index 0000000..2dc8676 Binary files /dev/null and b/volkov_rafael_lab_5/screens/img2.png differ diff --git a/volkov_rafael_lab_5/screens/img3.png b/volkov_rafael_lab_5/screens/img3.png new file mode 100644 index 0000000..442524b Binary files /dev/null and b/volkov_rafael_lab_5/screens/img3.png differ diff --git a/volkov_rafael_lab_5/screens/img4.png b/volkov_rafael_lab_5/screens/img4.png new file mode 100644 index 0000000..e023df7 Binary files /dev/null and b/volkov_rafael_lab_5/screens/img4.png differ diff --git a/volkov_rafael_lab_5/volkov_rafael_lab_5.sln b/volkov_rafael_lab_5/volkov_rafael_lab_5.sln new file mode 100644 index 0000000..6060349 --- /dev/null +++ b/volkov_rafael_lab_5/volkov_rafael_lab_5.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "volkov_rafael_lab_5", "volkov_rafael_lab_5\volkov_rafael_lab_5.csproj", "{02BDE79B-7993-4361-8AFA-E12E54B77931}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {02BDE79B-7993-4361-8AFA-E12E54B77931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02BDE79B-7993-4361-8AFA-E12E54B77931}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02BDE79B-7993-4361-8AFA-E12E54B77931}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02BDE79B-7993-4361-8AFA-E12E54B77931}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/volkov_rafael_lab_5/volkov_rafael_lab_5/Program.cs b/volkov_rafael_lab_5/volkov_rafael_lab_5/Program.cs new file mode 100644 index 0000000..3c96b04 --- /dev/null +++ b/volkov_rafael_lab_5/volkov_rafael_lab_5/Program.cs @@ -0,0 +1,124 @@ +using System.Diagnostics; + +class MatrixMultiplication +{ + static void Main() + { + int[] matrixSizes = { 100, 300, 500 }; + Console.Write("Введите количество потоков: "); + int numThreads = int.Parse(Console.ReadLine()); + + foreach (int size in matrixSizes) + { + Console.WriteLine($"Размер матрицы: {size}x{size}"); + var (sequentialTime, parallelTime) = Benchmark(size, numThreads); + + Console.WriteLine($"Время последовательного алгоритма: {sequentialTime:F6} секунд"); + Console.WriteLine($"Время параллельного алгоритма ({numThreads} потоков): {parallelTime:F6} секунд"); + + Console.WriteLine(new string('=', 30)); + } + } + + static double[,] SequentialMatrixMultiply(double[,] matrixA, double[,] matrixB) + { + int rowsA = matrixA.GetLength(0); + int colsB = matrixB.GetLength(1); + int colsA = matrixA.GetLength(1); + + double[,] result = new double[rowsA, colsB]; + + for (int i = 0; i < rowsA; i++) + { + for (int j = 0; j < colsB; j++) + { + for (int k = 0; k < colsA; k++) + { + result[i, j] += matrixA[i, k] * matrixB[k, j]; + } + } + } + + return result; + } + + static double[,] ParallelMatrixMultiply(double[,] matrixA, double[,] matrixB, int numThreads) + { + int rowsA = matrixA.GetLength(0); + int colsB = matrixB.GetLength(1); + int colsA = matrixA.GetLength(1); + + double[,] result = new double[rowsA, colsB]; + + int chunkSize = rowsA / numThreads; + + ManualResetEventSlim[] events = new ManualResetEventSlim[numThreads]; + + for (int i = 0; i < numThreads; i++) + { + events[i] = new ManualResetEventSlim(false); + int startRow = i * chunkSize; + int endRow = (i + 1 == numThreads) ? rowsA : (i + 1) * chunkSize; + + ThreadPool.QueueUserWorkItem(state => + { + MultiplyChunk(startRow, endRow, matrixA, matrixB, result); + events[(int)state].Set(); + }, i); + } + + WaitHandle.WaitAll(events.Select(e => (WaitHandle)e.WaitHandle).ToArray()); + + return result; + } + + static void MultiplyChunk(int startRow, int endRow, double[,] matrixA, double[,] matrixB, double[,] result) + { + int colsA = matrixA.GetLength(1); + + for (int i = startRow; i < endRow; i++) + { + for (int j = 0; j < result.GetLength(1); j++) + { + for (int k = 0; k < colsA; k++) + { + result[i, j] += matrixA[i, k] * matrixB[k, j]; + } + } + } + } + + static (double, double) Benchmark(int matrixSize, int numThreads) + { + double[,] matrixA = GenerateRandomMatrix(matrixSize, matrixSize); + double[,] matrixB = GenerateRandomMatrix(matrixSize, matrixSize); + + // Замер времени для последовательного алгоритма + Stopwatch stopwatch = Stopwatch.StartNew(); + double[,] sequentialResult = SequentialMatrixMultiply(matrixA, matrixB); + double sequentialTime = stopwatch.Elapsed.TotalSeconds; + + // Замер времени для параллельного алгоритма + stopwatch.Restart(); + double[,] parallelResult = ParallelMatrixMultiply(matrixA, matrixB, numThreads); + double parallelTime = stopwatch.Elapsed.TotalSeconds; + + return (sequentialTime, parallelTime); + } + + static double[,] GenerateRandomMatrix(int rows, int cols) + { + double[,] matrix = new double[rows, cols]; + Random random = new Random(); + + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < cols; j++) + { + matrix[i, j] = random.Next(10); + } + } + + return matrix; + } +} diff --git a/volkov_rafael_lab_5/volkov_rafael_lab_5/volkov_rafael_lab_5.csproj b/volkov_rafael_lab_5/volkov_rafael_lab_5/volkov_rafael_lab_5.csproj new file mode 100644 index 0000000..53387b9 --- /dev/null +++ b/volkov_rafael_lab_5/volkov_rafael_lab_5/volkov_rafael_lab_5.csproj @@ -0,0 +1,28 @@ + + + + Exe + net8.0 + enable + enable + + + + + README.md + + + screens\img1.png + + + screens\img2.png + + + screens\img3.png + + + screens\img4.png + + + +