distributed-computing/tasks/khalitova-am/lab_5/README.md
Khalitova Angelina d04e2f8c23 rep
2023-12-18 10:39:35 +04:00

6.0 KiB
Raw Blame History

Отчёт по лабораторной работе №5

Выполнила: студентка гр. ИСЭбд-41 Халитова А.М.

Создание приложения

В приложении были созданы следующие методы:

  • Заполнение матрицы рандомными значениями:
    private static int[][] GenerateRandomMatrix(int rows, int cols)
    {
        int[][] matrix = new int[rows][];

        Random rand = new Random();

        for (int i = 0; i < rows; i++)
        {
            matrix[i] = new int[cols];
            for (int j = 0; j < cols; j++)
            {
                matrix[i][j] = rand.Next(1, 10);
            }
        }

        return matrix;
    }
  • Перемножение матриц обычным алгоритмом:
    public static int[][] MultiplySequential(int[][] matrixA, int[][] matrixB)
    {
        int rowsA = matrixA.Length;
        int colsA = matrixA[0].Length;
        int colsB = matrixB[0].Length;

        int[][] result = new int[rowsA][];

        for (int i = 0; i < rowsA; i++)
        {
            result[i] = new int[colsB];

            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;
    }
  • Перемножение матриц параллельным алгоритмом:
 public static int[][] MultiplyParallel(int[][] matrixA, int[][] matrixB, int numThreads)
    {
        int rowsA = matrixA.Length;
        int colsA = matrixA[0].Length;
        int colsB = matrixB[0].Length;

        int[][] result = new int[rowsA][];

        Parallel.For(0, rowsA, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, i =>
        {
            result[i] = new int[colsB];

            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;
    }
  • Создание матриц различных размеров и с различным количеством потоков для параллельного алгоритма:
    [Benchmark]
    public void MultiplySequential_100x100()
    {
        int[][] matrixA = GenerateRandomMatrix(100, 100);
        int[][] matrixB = GenerateRandomMatrix(100, 100);
        MultiplySequential(matrixA, matrixB);
    }

    [Benchmark]
    public void MultiplyParallel_100x100_4TH()
    {
        int[][] matrixA = GenerateRandomMatrix(100, 100);
        int[][] matrixB = GenerateRandomMatrix(100, 100);
        MultiplyParallel(matrixA, matrixB, 4);
    }
    [Benchmark]
    public void MultiplyParallel_100x100_8TH()
    {
        int[][] matrixA = GenerateRandomMatrix(100, 100);
        int[][] matrixB = GenerateRandomMatrix(100, 100);
        MultiplyParallel(matrixA, matrixB, 8);

    }
    [Benchmark]
    public void MultiplyParallel_100x100_16TH()
    {
        int[][] matrixA = GenerateRandomMatrix(100, 100);
        int[][] matrixB = GenerateRandomMatrix(100, 100);
        MultiplyParallel(matrixA, matrixB, 16);

    }

    [Benchmark]
    public void MultiplySequential_300x300()
    {
        int[][] matrixA = GenerateRandomMatrix(300, 300);
        int[][] matrixB = GenerateRandomMatrix(300, 300);
        MultiplySequential(matrixA, matrixB);
    }

    [Benchmark]
    public void MultiplyParallel_300x300_4TH()
    {
        int[][] matrixA = GenerateRandomMatrix(300, 300);
        int[][] matrixB = GenerateRandomMatrix(300, 300);
        MultiplyParallel(matrixA, matrixB, 4);
    }
    [Benchmark]
    public void MultiplyParallel_300x300_8TH()
    {
        int[][] matrixA = GenerateRandomMatrix(300, 300);
        int[][] matrixB = GenerateRandomMatrix(300, 300);
        MultiplyParallel(matrixA, matrixB, 8);
    }
    [Benchmark]
    public void MultiplyParallel_300x300_16TH()
    {
        int[][] matrixA = GenerateRandomMatrix(300, 300);
        int[][] matrixB = GenerateRandomMatrix(300, 300);
        MultiplyParallel(matrixA, matrixB, 16);
    }
    [Benchmark]
    public void MultiplySequential_500x500()
    {
        int[][] matrixA = GenerateRandomMatrix(500, 500);
        int[][] matrixB = GenerateRandomMatrix(500, 500);
        MultiplySequential(matrixA, matrixB);
    }

    [Benchmark]
    public void MultiplyParallel_500x500_4TH()
    {
        int[][] matrixA = GenerateRandomMatrix(500, 500);
        int[][] matrixB = GenerateRandomMatrix(500, 500);
        MultiplyParallel(matrixA, matrixB, 4);
    }
    [Benchmark]
    public void MultiplyParallel_500x500_8TH()
    {
        int[][] matrixA = GenerateRandomMatrix(500, 500);
        int[][] matrixB = GenerateRandomMatrix(500, 500);
        MultiplyParallel(matrixA, matrixB, 8);
    }
    [Benchmark]
    public void MultiplyParallel_500x500_16TH()
    {
        int[][] matrixA = GenerateRandomMatrix(500, 500);
        int[][] matrixB = GenerateRandomMatrix(500, 500);
        MultiplyParallel(matrixA, matrixB, 16);
    }
  • Запуск приложения:
    static void Main(string[] args)
    {
        var summary = BenchmarkRunner.Run<MatrixMultiplication>();
        Console.ReadLine();
    }

Результаты работы приложения

По результатам работы: для матриц небольших размеров большое количество потоков не ускоряет (а в некоторых случаях замедляет) работу алгоритма, за счет излишнего переключения процессора. Для больших матриц увеличение количества потоков увеличивает скорость работы алгоритма. В сравнении с однопоточным алгоритмом, работа параллельного в несколько раз быстрее.