0

I have to multiply matrix by vector using class Task from TPL (it's labaratory work and I have to). I did it using Parallel For and it works but now I'm stuck because I have no idea how to implement it using tasks.

public static int[] matxvecParallel(int [,] mat, int[] vec)ParallelFor
    {            
        int[] res = new int[mat.GetLength(0)];
        Parallel.For(0, mat.GetLength(0), i =>
        {
            for (int k = 0; k < mat.GetLength(1); k++)
            {
                res[i] += mat[i, k] * vec[k];
            }

        });
        return res;
    }

I did something stupid to find out how tasks works and I still don't understand. How to change my code?

public static int[] matxvecTask(int[,] mat, int[] vec) 
    {
        int[] res = new int[mat.GetLength(0)];
        int countTasks = 4;
        Task[] arrayOfTasks = new Task[countTasks];

        for (int k = 0; k < mat.GetLength(0); k++)
        {
            for(int i = 0; i < countTasks; i++)
            {
            int index = i;
            arrayOfTasks[index] = Task.Run(() =>
                {
                    for (int j = 0; j < mat.GetLength(1); j++)
                    {
                        res[i] += mat[i, j] * vec[j];
                    }
                });
            }
        }
        return res;
    }
Lika Barken
  • 45
  • 1
  • 8
  • You aren't doing anything asynchronous so there's no need to use Tasks; it would just add overhead. – Johnathan Barclay Apr 22 '20 at 16:01
  • Why do you want to do this with tasks? This really is something that is clear cut for parallel programming. `Task` represents some work. That work can be done or ongoing. You can wait for that work to finish and once it's done and it has a result you can use that result. Tasks might be excecuted in parallel, they might not be. For a case like this where you just want to do some cpu bound work in parallel, tasks won't gain you anything –  Apr 22 '20 at 16:03

1 Answers1

0

To make it work, change this line to use index instead of i:

res[index] += mat[index, j] * vec[j];

When you use i, you fall in the trap of closures.

Then, you should also wait for all the tasks to complete before moving on to the next iteration:

Task.WaitAll(arrayOfTasks);

Now, you will gain absolutely nothing if you replace Parallel.For with tasks. You only make your code more complicated. Both tasks and Parallel will execute your computations on the thread pool. However, Parallel is optimized especially for the purpose and it easier to write and read.

Nick
  • 4,787
  • 2
  • 18
  • 24