M
M
Mister_krid2021-03-26 21:28:14
C++ / C#
Mister_krid, 2021-03-26 21:28:14

How to reduce the method and improve the code?

Krch made a task: Implement two ways of processing elements of two-dimensional arrays
(matrices): serial and parallel.
With the sequential method, the array elements are processed in one
thread, with the parallel method, in m threads (the m parameter must be passed to
the processing function). In this case, the array is divided into m parts, and each part
is processed in a separate thread.
Processing operation - 1) finding the difference of two matrices
2) multiplying the resulting matrix by a given number. Matrices of the
same size with elements of type int and writing the value of the difference to the first
matrix. Matrices with a size of 1000 columns by 1000 rows must be filled
before calling the processing function with random numbers.
The execution time of a processing function should be measured by finding the
difference between the start time and end time of processing.
The test results should show the dependence of the
execution time of the processing operation on the parameter m (it is necessary to measure
for m in the range of 1...8).
So the method with parallel computing turned out to be very big, and indeed it seems to me that I was too smart.
Can you advise on the best way to do it and how to analyze sequential and parallel computing (I saw somewhere that a visual can display a performance graph, but I don’t understand how to do it visually. Can a resource help some thread)

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;
        }
    }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
porev44067, 2021-03-27
@Mister_krid

Most likely, you need to print the elapsed time for each number of threads in the range 1...8. For tests, compile in Release and run the executable directly.

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
        }
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question