@Mister_krid

Как уменьшить метод и улучшить код?

Крч сделал задачку: Реализовать два способа обработки элементов двумерных массивов
(матриц): последовательный и параллельный.
При последовательном способе элементы массива обрабатываются в одном
потоке, при параллельном – в m потоках (параметр m должен передаваться в
функцию обработки). При этом массив разбивается на m частей, и каждая часть
обрабатывается в отдельном потоке.
Операция обработки – 1) нахождение разности двух матриц
2)умножение получившейся матрицы на заданное число. Матрицы
одинакового размера с элементами типа int и запись значения разности в первую
матрицу. Матрицы размером 1000 столбцов на 1000 строк, должны заполняться
перед вызовом функции обработки случайными числами.
Время выполнения функции обработки должно измеряться нахождением
разницы между временем начала и временем окончания обработки.
Результаты тестирования должны показывать зависимость времени
выполнения операции обработки от параметра m (необходимо провести измерения
для m в диапазоне 1...8).
Так вот метод с параллельными вычислениями получился оч большой, да и вообще мне кажется я перемудрил.
Можете посоветовать как лучше сделать и как провести анализ последовательного и паралельного вычисления(я где то видел что визуалка может выводить график производительности, но как это сделать наглядно я не понимаю. мож ресурс в помощь какой нить)
class Program
    {
        static int number = 0; //число умноженное на матрицу

        static void Main(string[] args)
        {
            
            Console.Write("Строки - ");
            var str = Int32.Parse(Console.ReadLine());

            Console.Write("Столбцы - ");
            var column = Int32.Parse(Console.ReadLine());

            Console.Write("Потоки - ");
            var threadCount = Int32.Parse(Console.ReadLine());

            int[,] oneMatrx = new int[str, column];
            int[,] twoMatrx = new int[str, column];
                  
            ToMatrx(ref oneMatrx);
            Console.WriteLine();

            ToMatrx(ref twoMatrx);
            Console.WriteLine();

            // var startTime = System.Diagnostics.Stopwatch.StartNew();

            DateTime dt1, dt2;
            dt1 = DateTime.Now;

            DifferenceMatrx(ref oneMatrx, twoMatrx);
            Console.WriteLine();

            MultiByNumber(oneMatrx, number);

            dt2 = DateTime.Now;
            TimeSpan sd = dt2 - dt1;
            Console.WriteLine("Линейное" + sd.TotalMilliseconds);
            //startTime.Stop(); //останавливаем счетчик 
            //var resultTime = startTime.Elapsed;
            // Console.WriteLine(String.Format("{0:00}.{1:000}",
            //     resultTime.Seconds,
            //     resultTime.Milliseconds));
            Console.WriteLine(ThreadMtrx(oneMatrx, twoMatrx, threadCount));

        }

        static void ToMatrx(ref int[,] array) // change length array
        {
            Random randomValue = new Random();

            for (int i = 0; i < array.GetLength(0); i++)
            {

                for (int j = 0; j < array.GetLength(1); j++)
                {
                    array[i, j] = randomValue.Next(1, 1000);
                    //Console.WriteLine($"value[{i},{j}] = {array[i, j]}");
                }

            }

        }

        static void DifferenceMatrx(ref int[,] oneArray, int[,] twoArray)
        {
            //Console.WriteLine("Matrix difference:");
            for (int i = 0; i < oneArray.GetLength(0); i++)
            {
                for (int j = 0; j < twoArray.GetLength(1); j++)
                {
                    oneArray[i, j] = oneArray[i, j] - twoArray[i, j];
                    //Console.WriteLine($"value[{i},{j}] = {oneArray[i, j]}");
                }
            }

        }

        static void MultiByNumber(int[,] oneArray, int number)
        {
            //Console.WriteLine($"Matrix multiplied by a {number}:");
            for (int i = 0; i < oneArray.GetLength(0); i++)
            {
                for (int j = 0; j < oneArray.GetLength(1); j++)
                {
                    oneArray[i, j] = oneArray[i, j] * number;
                    //Console.WriteLine($"value[{i},{j}] = {oneArray[i, j]}");
                }
            }
        }


        static double ThreadMtrx(int[,] oneMatrx, int[,] twoMatrx, int threadCount)
        {
            var each = oneMatrx.GetLength(0) / threadCount;
            int last = oneMatrx.GetLength(0) % threadCount;
            int iM = 0;

            DateTime dt1, dt2;
            dt1 = DateTime.Now;

            Thread[] threads = new Thread[threadCount];

            for (int i = 0; i < threadCount; i++)
            {
                int iBeg;
                int iEnd;

                if (i < last)
                {
                    iBeg = iM;
                    iEnd = iM + each + 1;

                    iM += each + 1;
                }
                else
                {
                    iBeg = iM;
                    iEnd = iM + each;

                    iM += each;
                }

                Random randomValue = new Random();
                threads[i] = new Thread((obj) =>
                {
                    for (int index = 0; index < oneMatrx.GetLength(0); index++)
                    {
                        for (int j = iBeg; j < iEnd; j++)
                        {
                            oneMatrx[index, j] = oneMatrx[index, j] - twoMatrx[index, j];
                            oneMatrx[index, j] = oneMatrx[index, j] * number;
                            // Console.WriteLine($"Поток:[{i}]value[{index},{j}] = {array[index, j]}");
                        }
                    }
                });
                threads[i].Start();
            }
            
            for (int i = 0; i < threadCount; i++)
                threads[i].Join();
            
            dt2 = DateTime.Now;
            TimeSpan sw = dt2 - dt1;
            return sw.TotalMilliseconds;
        }
    }
  • Вопрос задан
  • 390 просмотров
Решения вопроса 1
@porev44067
Скорее всего, нужно вывести затраченное время для каждого количества потоков в диапазоне 1...8. Для тестов компилируй в Release и запускай исполняемый файл напрямую.
using System;
using System.Threading;

namespace MatrixTest
{
    class Program
    {
        static void GenerateMatrix(ref int[,] matrix)
        {
            Random random = new Random();

            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                    matrix[i, j] = random.Next(1, 1000);
            }
        }

        static int[,] ProcessMatrix(int[,] matrix1, int[,] matrix2, int number, out double elapsedTime)
        {
            DateTime startTime = DateTime.Now;

            for (int i = 0; i < matrix1.GetLength(0); i++)
            {
                for (int j = 0; j < matrix2.GetLength(1); j++)
                {
                    matrix1[i, j] -= matrix2[i, j];
                    matrix1[i, j] *= number;
                }
            }

            elapsedTime = (DateTime.Now - startTime).TotalMilliseconds;

            return matrix1;
        }

        static int[,] ProcessMatrixParallel(int[,] matrix1, int[,] matrix2, int number, int threadCount, out double elapsedTime)
        {
            int length = matrix1.GetLength(0);
            int each = length / threadCount;
            int last = length % threadCount;

            var threads = new Thread[threadCount];

            for (int t = 0; t < threadCount; t++)
            {
                int start = t * each;
                int end = start + each;
                if (t == threadCount - 1)
                    end += last;

                threads[t] = new Thread((obj) =>
                {
                    for (int i = start; i < end; i++)
                    {
                        for (int j = 0; j < length; j++)
                        {
                            matrix1[i, j] -= matrix2[i, j];
                            matrix1[i, j] *= number;
                        }
                    }
                });
            }

            DateTime startTime = DateTime.Now;

            for (int i = 0; i < threads.Length; i++)
                threads[i].Start();

            for (int i = 0; i < threads.Length; i++)
                threads[i].Join();

            elapsedTime = (DateTime.Now - startTime).TotalMilliseconds;

            return matrix1;
        }

        static void Main()
        {
            int rows, cols;
            rows = cols = 1000;

            //Console.Write("Строки - ");
            //var rows = int.Parse(Console.ReadLine());

            //Console.Write("Столбцы - ");
            //var cols = int.Parse(Console.ReadLine());

            Console.Write("Число - ");
            int number = int.Parse(Console.ReadLine());
            //int number = new Random().Next();

            //Console.Write("Потоки - ");
            //var threads = int.Parse(Console.ReadLine());

            int[,] matrix1 = new int[rows, cols];
            int[,] matrix2 = new int[rows, cols];

            GenerateMatrix(ref matrix1);
            GenerateMatrix(ref matrix2);

            ProcessMatrix(matrix1, matrix2, number, out double elapsedTime);

            Console.WriteLine($"Последовательный метод: {elapsedTime} мс.");

            for (int i = 1; i <= 8; i++)
            {
                ProcessMatrixParallel(matrix1, matrix2, number, i, out double elapsedTimeParallel);
                Console.WriteLine($"Параллельный метод ({i} п.): {elapsedTimeParallel} мс.");
            }

#if RELEASE
            Console.ReadLine();
#endif
        }
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы