109 lines
3.3 KiB
Markdown
109 lines
3.3 KiB
Markdown
|
# Отчет по лабораторной работе №6
|
|||
|
|
|||
|
Выполнил студент гр. ИСЭбд-41 Савицкий А.В.
|
|||
|
|
|||
|
## Создание приложения
|
|||
|
|
|||
|
Выбрал язык C#, Консольное приложение.
|
|||
|
Установил библиотеку BenchmarkDotNet для замера производительности.
|
|||
|
|
|||
|
Сам алгоритм.
|
|||
|
``` cs
|
|||
|
public double DeterminantOfMatrix(double[,] matrix, int threadCount)
|
|||
|
{
|
|||
|
int size = matrix.GetLength(0);
|
|||
|
|
|||
|
if (size == 1)
|
|||
|
{
|
|||
|
return matrix[0, 0];
|
|||
|
}
|
|||
|
else if (size == 2)
|
|||
|
{
|
|||
|
return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
double determinant = 0;
|
|||
|
|
|||
|
Parallel.For(0, size, new ParallelOptions { MaxDegreeOfParallelism = threadCount },
|
|||
|
(i) =>
|
|||
|
{
|
|||
|
double[,] subMatrix = GetSubMatrix(matrix, i);
|
|||
|
double subDeterminant = matrix[0, i] * Determinant(subMatrix);
|
|||
|
double value = Math.Pow(-1, i) * subDeterminant;
|
|||
|
lock (lockObject)
|
|||
|
{
|
|||
|
determinant += value;
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
return determinant;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static double[,] GetSubMatrix(double[,] matrix, int columnIndex)
|
|||
|
{
|
|||
|
int size = matrix.GetLength(0);
|
|||
|
double[,] subMatrix = new double[size - 1, size - 1];
|
|||
|
|
|||
|
for (int i = 1; i < size; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < size; j++)
|
|||
|
{
|
|||
|
if (j < columnIndex)
|
|||
|
{
|
|||
|
subMatrix[i - 1, j] = matrix[i, j];
|
|||
|
}
|
|||
|
else if (j > columnIndex)
|
|||
|
{
|
|||
|
subMatrix[i - 1, j - 1] = matrix[i, j];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return subMatrix;
|
|||
|
}
|
|||
|
|
|||
|
static double Determinant(double[,] matrix)
|
|||
|
{
|
|||
|
int size = matrix.GetLength(0);
|
|||
|
|
|||
|
if (size == 1)
|
|||
|
{
|
|||
|
return matrix[0, 0];
|
|||
|
}
|
|||
|
else if (size == 2)
|
|||
|
{
|
|||
|
return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
double determinant = 0;
|
|||
|
|
|||
|
for (int i = 0; i < size; i++)
|
|||
|
{
|
|||
|
double[,] subMatrix = GetSubMatrix(matrix, i);
|
|||
|
|
|||
|
determinant += (int)Math.Pow(-1, i) * matrix[0, i] * Determinant(subMatrix);
|
|||
|
}
|
|||
|
|
|||
|
return determinant;
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Проверка работы на матрице 3х3
|
|||
|
![](pic/1.png)
|
|||
|
|
|||
|
## Бенчмарки
|
|||
|
|
|||
|
Протестируем обычный и параллельный алгоритм определение детерминанта на различной размерности матрицы.
|
|||
|
|
|||
|
В ходе экспериментов было установлено, что обработка матрицы размеров больше 12х12 занимает слишком много времени, поэтому для тестирования возьмем матрицы 5х5, 8х8 и 11х11.
|
|||
|
|
|||
|
Для тестирование запускаю алгоритм в 1 поток и в 12 потоков
|
|||
|
|
|||
|
![](pic/2.png)
|
|||
|
|
|||
|
Вывод: Параллельный алгоритм работает быстрее только при наличии большого количества операций. Если операций не так много, то обычный алгоритм справляется быстрее.
|