# Отчёт по лабораторной работе №6 Выполнила: студентка гр. ИСЭбд-41 Халитова А.М. ## Создание приложения В приложении были созданы следующие методы: - Заполнение матрицы рандомными значениями: ``` public static double[][] GenerateRandomMatrix(int rows, int cols) { double[][] matrix = new double[rows][]; Random rand = new Random(); for (int i = 0; i < rows; i++) { matrix[i] = new double[cols]; for (int j = 0; j < cols; j++) { matrix[i][j] = rand.Next(1, 10); } } return matrix; } ``` - Метод создания подматрицы для удаления строки и столбца в вычислении определителя: ``` private static double[][] GetSubMatrix(double[][] matrix, int rowToRemove, int colToRemove) { int size = matrix.Length; double[][] subMatrix = new double[size - 1][]; for (int i = 0, newRow = 0; i < size; i++) { if (i != rowToRemove) { subMatrix[newRow] = new double[size - 1]; for (int j = 0, newCol = 0; j < size; j++) { if (j != colToRemove) { subMatrix[newRow][newCol] = matrix[i][j]; newCol++; } } newRow++; } } return subMatrix; } ``` - Метод вычисления детерминанта обычным алгоритмом: ``` public static double DeterminantSequential(double[][] matrix) { int size = matrix.Length; if (size == 1) { return matrix[0][0]; } if (size == 2) { return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; } double determinant = 0; for (int i = 0; i < size; i++) { double sign = (i % 2 == 0) ? 1 : -1; double cofactor = sign * matrix[0][i] * DeterminantSequential(GetSubMatrix(matrix, 0, i)); determinant += cofactor; } return determinant; } ``` - Метод вычисления детерминанта параллельным алгоритмом: ``` public static double DeterminantParallel(double[][] matrix, int numThreads) { int size = matrix.Length; if (size == 1) { return matrix[0][0]; } if (size == 2) { return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; } double determinant = 0; Parallel.For(0, size, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, i => { double sign = (i % 2 == 0) ? 1 : -1; double cofactor = sign * matrix[0][i] * DeterminantSequential(GetSubMatrix(matrix, 0, i)); determinant += cofactor; }); return determinant; } ``` - Методы генерации матриц различных размеров и с различным числом потоков. Поскольку ресурсы машины не позволяют вычислить детерминанту для больших матриц (процесс занимает большое количество времени и памяти, происходит зависание), вычислять будем для матриц меньших размеров (2, 4, 8): ``` [Benchmark] public void DeterminantSequential_2x2() { double[][] matrix = GenerateRandomMatrix(2, 2); DeterminantSequential(matrix); } [Benchmark] public void DeterminantParallel_2x2_4TH() { double[][] matrix = GenerateRandomMatrix(2, 2); DeterminantParallel(matrix, 4); } [Benchmark] public void DeterminantParallel_2x2_8TH() { double[][] matrix = GenerateRandomMatrix(2, 2); DeterminantParallel(matrix, 8); } [Benchmark] public void DeterminantParallel_2x2_16TH() { double[][] matrix = GenerateRandomMatrix(2, 2); DeterminantParallel(matrix, 16); } [Benchmark] public void DeterminantSequential_4x4() { double[][] matrix = GenerateRandomMatrix(4, 4); DeterminantSequential(matrix); } [Benchmark] public void DeterminantParallel_4x4_4TH() { double[][] matrix = GenerateRandomMatrix(4, 4); DeterminantParallel(matrix, 4); } [Benchmark] public void DeterminantParallel_4x4_8TH() { double[][] matrix = GenerateRandomMatrix(4, 4); DeterminantParallel(matrix, 8); } [Benchmark] public void DeterminantParallel_4x4_16TH() { double[][] matrix = GenerateRandomMatrix(4, 4); DeterminantParallel(matrix, 16); } [Benchmark] public void DeterminantSequential_8x8() { double[][] matrix = GenerateRandomMatrix(8, 8); DeterminantSequential(matrix); } [Benchmark] public void DeterminantParallel_8x8_4TH() { double[][] matrix = GenerateRandomMatrix(8, 8); DeterminantParallel(matrix, 4); } [Benchmark] public void DeterminantParallel_8x8_8TH() { double[][] matrix = GenerateRandomMatrix(8, 8); DeterminantParallel(matrix, 8); } [Benchmark] public void DeterminantParallel_8x8_16TH() { double[][] matrix = GenerateRandomMatrix(8, 8); DeterminantParallel(matrix, 16); } ``` Запуск приложения происходит с помощью строки `var summary = BenchmarkRunner.Run();`. ## Результаты работы приложения ![](shot.PNG) Вывод: по результатам работы, для малых матриц парралельный алгоритм не дает прироста в скорости работы. Для матрицы 8 на 8 дает прирост только распараллеливание на малое число потоков. Для вычисления детерминанта больших матриц (больше, чем 8 на 8) не хватает вычислительной мощности моего процессора, но можно предположить что в этом случае увеличение числа потоков приводило бы к увеличению скорости работы.