diff --git a/tasks/ostrovskaya-sf/lab_6/README.md b/tasks/ostrovskaya-sf/lab_6/README.md new file mode 100644 index 0000000..2060260 --- /dev/null +++ b/tasks/ostrovskaya-sf/lab_6/README.md @@ -0,0 +1,66 @@ +# Отчет по лабораторной работе №5 + +Выполнила студентка гр. ИСЭбд-41 Островская С.Ф. + +## Создание приложения + +Было выбрано консольное приложение, язык программирования - c#. + +Обычный алгоритм: + +```cs +static void SequentialDeterminantCalculation(int matrixSize, int lowerLimit, int upperLimit) + { + int[][] randomMatrix = GenerateRandomMatrix(matrixSize, lowerLimit, upperLimit); + + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + int result = Determinant(randomMatrix); + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + Console.WriteLine($"Последовательный детерминант: {result}"); + Console.WriteLine($"Последовательное время: {elapsedTime.TotalSeconds:F7} секунд"); + } +``` +Параллельный алгоритм: + +```cs +static void ParallelDeterminantCalculation(int matrixSize, int lowerLimit, int upperLimit, int numProcesses) + { + int[][] randomMatrix = GenerateRandomMatrix(matrixSize, lowerLimit, upperLimit); + + int[][] matricesToProcess = new int[matrixSize][]; + for (int col = 0; col < matrixSize; col++) + { + matricesToProcess[col] = Submatrix(randomMatrix, 0, col)[0]; + } + + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + int[] determinants = new int[matrixSize]; + Parallel.For(0, matrixSize, new ParallelOptions { MaxDegreeOfParallelism = numProcesses }, col => + { + determinants[col] = Determinant(new int[][] { matricesToProcess[col] }); + }); + + int result = 0; + for (int col = 0; col < matrixSize; col++) + { + result += ((-1) * col) * randomMatrix[0][col] * determinants[col]; + } + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + Console.WriteLine($"Параллельный детерминант: {result}"); + Console.WriteLine($"Параллельное время: {elapsedTime.TotalSeconds:F7} секунд"); + } +``` + +## Бенчмарки + +Для примера была взята матрица размерностью 10х10, поскольку для матриц больших размеров детерминант вычисляется слишком долго. + + +![](pic/pic1.jpg) + + +``Вывод``: Обыный алгоритм работает быстрее, если количество элементов не слишком много. Параллельный же алгоритм работает быстрее только при наличии большого количества операций и данных. \ No newline at end of file diff --git a/tasks/ostrovskaya-sf/lab_6/lab_6_matrix/lab_6_matrix/Program.cs b/tasks/ostrovskaya-sf/lab_6/lab_6_matrix/lab_6_matrix/Program.cs index 07c510d..165e3dd 100644 --- a/tasks/ostrovskaya-sf/lab_6/lab_6_matrix/lab_6_matrix/Program.cs +++ b/tasks/ostrovskaya-sf/lab_6/lab_6_matrix/lab_6_matrix/Program.cs @@ -1,170 +1,135 @@ using System; using System.Diagnostics; -using System.Threading; +using System.Threading.Tasks; class Program { - static void Main(string[] args) + static void SequentialDeterminantCalculation(int matrixSize, int lowerLimit, int upperLimit) { - int matrixSize = 3; // размерность матрицы + int[][] randomMatrix = GenerateRandomMatrix(matrixSize, lowerLimit, upperLimit); - // Создаем матрицу - int[,] matrix = new int[matrixSize, matrixSize]; + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + int result = Determinant(randomMatrix); + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + Console.WriteLine($"Последовательный детерминант: {result}"); + Console.WriteLine($"Последовательное время: {elapsedTime.TotalSeconds:F7} секунд"); + } - // Заполняем матрицу случайными значениями + static void ParallelDeterminantCalculation(int matrixSize, int lowerLimit, int upperLimit, int numProcesses) + { + int[][] randomMatrix = GenerateRandomMatrix(matrixSize, lowerLimit, upperLimit); + + int[][] matricesToProcess = new int[matrixSize][]; + for (int col = 0; col < matrixSize; col++) + { + matricesToProcess[col] = Submatrix(randomMatrix, 0, col)[0]; + } + + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + int[] determinants = new int[matrixSize]; + Parallel.For(0, matrixSize, new ParallelOptions { MaxDegreeOfParallelism = numProcesses }, col => + { + determinants[col] = Determinant(new int[][] { matricesToProcess[col] }); + }); + + int result = 0; + for (int col = 0; col < matrixSize; col++) + { + result += ((-1) * col) * randomMatrix[0][col] * determinants[col]; + } + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + Console.WriteLine($"Параллельный детерминант: {result}"); + Console.WriteLine($"Параллельное время: {elapsedTime.TotalSeconds:F7} секунд"); + } + + static int[][] GenerateRandomMatrix(int matrixSize, int lowerLimit, int upperLimit) + { Random random = new Random(); + int[][] matrix = new int[matrixSize][]; + for (int i = 0; i < matrixSize; i++) { + matrix[i] = new int[matrixSize]; for (int j = 0; j < matrixSize; j++) { - matrix[i, j] = random.Next(1, 10); + matrix[i][j] = random.Next(lowerLimit, upperLimit); } } - - Console.Write("Введите количество потоков: "); - int numThreads = int.Parse(Console.ReadLine()); - - int detSequential = CalculateDeterminantSequential(matrix); - Console.WriteLine($"Детерминант (обычный алгоритм): {detSequential}"); - - int detParallel = CalculateDeterminantParallel(matrix, numThreads); - Console.WriteLine($"Детерминант (параллельный алгоритм, {numThreads} поток): {detParallel}"); - - // Бенчмарки - Console.WriteLine("\nБенчмарки:"); - - // Последовательный алгоритм - Console.WriteLine("Последовательный алгоритм:"); - - // Матрица 5x5 - matrixSize = 5; - matrix = new int[matrixSize, matrixSize]; - FillMatrix(matrix, random); - Stopwatch sw1 = new Stopwatch(); - sw1.Start(); - detSequential = CalculateDeterminantSequential(matrix); - sw1.Stop(); - TimeSpan elapsedTime1 = sw1.Elapsed; - Console.WriteLine($"Матрица {matrixSize}x{matrixSize}: Время выполнения - {elapsedTime1.TotalSeconds:F7} с"); - - // Матрица 10x10 - matrixSize = 10; - matrix = new int[matrixSize, matrixSize]; - FillMatrix(matrix, random); - sw1 = new Stopwatch(); - sw1.Start(); - detSequential = CalculateDeterminantSequential(matrix); - sw1.Stop(); - elapsedTime1 = sw1.Elapsed; - Console.WriteLine($"Матрица {matrixSize}x{matrixSize}: Время выполнения - {elapsedTime1.TotalSeconds:F7} с"); - - // Параллельный алгоритм - Console.WriteLine("\nПараллельный алгоритм:"); - - // Матрица 5x5 - matrixSize = 5; - matrix = new int[matrixSize, matrixSize]; - FillMatrix(matrix, random); - numThreads = 4; - Stopwatch sw2 = new Stopwatch(); - sw2.Start(); - detParallel = CalculateDeterminantParallel(matrix, numThreads); - sw2.Stop(); - TimeSpan elapsedTime2 = sw2.Elapsed; - Console.WriteLine($"Матрица {matrixSize}x{matrixSize}, {numThreads} потоков: Время выполнения - {elapsedTime2.TotalSeconds:F7} с"); - - // Матрица 10x10 - matrixSize = 10; - matrix = new int[matrixSize, matrixSize]; - FillMatrix(matrix, random); - numThreads = 4; - sw2 = new Stopwatch(); - sw2.Start(); - detParallel = CalculateDeterminantParallel(matrix, numThreads); - sw2.Stop(); - elapsedTime2 = sw2.Elapsed; - Console.WriteLine($"Матрица {matrixSize}x{matrixSize}, {numThreads} потоков: Время выполнения - {elapsedTime2.TotalSeconds:F7} с"); + return matrix; } - static void FillMatrix(int[,] matrix, Random random) + static int[][] Submatrix(int[][] matrix, int rowToDelete, int colToDelete) { - int n = matrix.GetLength(0); - for (int i = 0; i < n; i++) + int size = matrix.Length - 1; + int[][] submatrix = new int[size][]; + + int rowIndex = 0; + + for (int i = 0; i < matrix.Length; i++) { - for (int j = 0; j < n; j++) + if (i == rowToDelete) + continue; + + submatrix[rowIndex] = new int[size]; + + int colIndex = 0; + for (int j = 0; j < matrix.Length; j++) { - matrix[i, j] = random.Next(10); // Здесь можно указать диапазон случайных значений, в данном случае от 0 до 9 + if (j == colToDelete) + continue; + + submatrix[rowIndex][colIndex] = matrix[i][j]; + colIndex++; } + + rowIndex++; } + + return submatrix; } - static int CalculateDeterminantSequential(int[,] matrix) + static int Determinant(int[][] matrix) { - int n = matrix.GetLength(0); + int n = matrix.Length; if (n == 1) { - return matrix[0, 0]; + return matrix[0][0]; } else if (n == 2) { - return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0]; + return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; } else { int determinant = 0; + for (int j = 0; j < n; j++) { - int[,] subMatrix = new int[n - 1, n - 1]; - for (int i = 1; i < n; i++) - { - for (int k = 0; k < j; k++) - { - subMatrix[i - 1, k] = matrix[i, k]; - } - for (int k = j + 1; k < n; k++) - { - subMatrix[i - 1, k - 1] = matrix[i, k]; - } - } - determinant += (int)Math.Pow(-1, j) * matrix[0, j] * CalculateDeterminantSequential(subMatrix); + int[][] submatrix = Submatrix(matrix, 0, j); + int subDeterminant = Determinant(submatrix); + determinant += ((-1) * j) * matrix[0][j] * subDeterminant; } + return determinant; } } - static int CalculateDeterminantParallel(int[,] matrix, int numThreads) + static void Main(string[] args) { - int n = matrix.GetLength(0); - if (n == 1) + SequentialDeterminantCalculation(10, 0, 10); + Console.WriteLine(); + + int[] numThreads = { 1, 2, 4, 6, 8, 12, 16, 32 }; + + for (int i = 0; i < 8; i++) { - return matrix[0, 0]; - } - else if (n == 2) - { - return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0]; - } - else - { - int determinant = 0; - Parallel.For(0, n, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, j => - { - int[,] subMatrix = new int[n - 1, n - 1]; - for (int i = 1; i < n; i++) - { - for (int k = 0; k < j; k++) - { - subMatrix[i - 1, k] = matrix[i, k]; - } - for (int k = j + 1; k < n; k++) - { - subMatrix[i - 1, k - 1] = matrix[i, k]; - } - } - int subDeterminant = CalculateDeterminantParallel(subMatrix, numThreads); - Interlocked.Add(ref determinant, (int)Math.Pow(-1, j) * matrix[0, j] * subDeterminant); - }); - return determinant; + Console.WriteLine($"Количество потоков: {numThreads[i]}"); + ParallelDeterminantCalculation(10, 0, 10, numThreads[i]); } } -} \ No newline at end of file +} diff --git a/tasks/ostrovskaya-sf/lab_6/pic/pic1.jpg b/tasks/ostrovskaya-sf/lab_6/pic/pic1.jpg new file mode 100644 index 0000000..095490c Binary files /dev/null and b/tasks/ostrovskaya-sf/lab_6/pic/pic1.jpg differ