distributed-computing/tasks/khalitova-am/lab_6/README.md
Khalitova Angelina 5bca7da18d add
2023-12-18 12:25:15 +04:00

199 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Отчёт по лабораторной работе №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<MatrixDeterminant>();`.
## Результаты работы приложения
![](shot.PNG)
Вывод: по результатам работы, для малых матриц парралельный алгоритм не дает прироста в скорости работы. Для матрицы 8 на 8 дает прирост только распараллеливание на малое число потоков. Для вычисления детерминанта больших матриц (больше, чем 8 на 8) не хватает вычислительной мощности моего процессора, но можно предположить что в этом случае увеличение числа потоков приводило бы к увеличению скорости работы.