1

I'm new to multithreading, and I made a simple code through what I have learned while surfing.

                Task[] tasks = new Task[B.Col];
                for(int j = 0; j < B.Col; j++)
                {
                    tasks[j] = Task.Run(() =>
                    {
                        for (int k = 0; k < A.Col; k++)
                        {
                            C[i, j] += A[i, k] * B[k, j];
                        }
                    });
                }
                /*
                for(int j = 0; j < B.Col; j++)
                {
                    for(int k = 0; k < A.Col; k++)
                    {
                        C[i, j] += A[i, k] * B[k, j];
                    }
                }
                */

I want to check if this is the right way to 'multithread'ize the code below. If this code is not that efficient, would you please help me to find a better way?

user5876164
  • 471
  • 3
  • 15
  • Where did you define `i`? I don't see it. – George Alexandria Aug 27 '17 at 12:13
  • @GeorgeAlexandria i is outside the code, the code is in another for loop. – user5876164 Aug 27 '17 at 12:14
  • Possible duplicate of [When to use a Parallel.ForEach loop instead of a regular foreach?](https://stackoverflow.com/questions/12251874/when-to-use-a-parallel-foreach-loop-instead-of-a-regular-foreach) – mjwills Aug 27 '17 at 12:19
  • Why not let him get his example working first instead of throwing in the Parallel.For? – Aydin Aug 27 '17 at 12:21
  • @mjwills I tried to use ForEach, but since I had to use j, I just used for loop. Are there any suggestions of using ForEach while using j? – user5876164 Aug 27 '17 at 12:33
  • https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-simple-parallel-for-loop – mjwills Aug 27 '17 at 12:34
  • 2
    Couple of notes here: for one, this code won't benefit from using Tasks, it is way to small. Furthermore, use Tasks for IO bound operations and Parallel.For for CPU bound operations (like computations). See https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/data-parallelism-task-parallel-library – Peter Bons Aug 27 '17 at 12:40

1 Answers1

2

To make what your attempting work, you need a few small modifications

Object thisLock = new Object();

int totalThreads = 3;
Task[] tasks = new Task[totalThreads];
for (int j = 0; j < totalThreads; j++)
{
    // We're taking a reference of the value of `j`, 
    // this is because on each iteration, the value of `j` 
    // will change and cause issues in your threads.
    var jRef = j;
    
    tasks[jRef] = Task.Run(() =>
    {
        for (int k = 0; k < totalThreads; k++)
        {
            lock (thisLock)
            {
                // Perform operations on shared resources
            }
        }
    });
}

Task.WaitAll(tasks);
miken32
  • 42,008
  • 16
  • 111
  • 154
Aydin
  • 15,016
  • 4
  • 32
  • 42
  • This seems a bit tricky to me. Why are you using jRef instead of j, and if I have to make (row times col) total threads, how should I actually apply that to the code? (=> Why is the definition of tasks outside the for loop) – user5876164 Aug 27 '17 at 12:28
  • @user5876164 Why not start small, you're attempting to bite more than you can chew off. Specify a set number of threads before hand instead of setting it dynamically. `j` Is set to `jRef` because in your example you use `j` inside of the thread you've just created. On every iteration the value of `j` **changes**, so this part of your code `C[i, j] += A[i, k] * B[k, j];` will never be accurate. if `j` was == 1 when you started a thread, `j` would change on the second iteration to the value of 2 and it would mess up all your calculations – Aydin Aug 27 '17 at 12:36
  • @user5876164 what is kja and all these other variables, show what they are because you're asking me to explain your code without showing me your code – Aydin Aug 27 '17 at 12:41
  • 4
    Didn't downvote, but: doesn't putting a lock around the whole code running inside the task makes it less worth doing it and kind of defeats the purpose? – Peter Bons Aug 27 '17 at 12:48
  • @PeterBons Yup, the fact that he's dealing with an array (which will be accessed by multiple threads at the same time performing write operations) made me uneasy, I would suggest a concurrent collection but I wanted to see what I was dealing with first – Aydin Aug 27 '17 at 12:49
  • Yeah, that is the problem of the OP trying to make a (too) simple example to learn and thereby running into other issues instead of using real world code. Upvoted for it is a working solution – Peter Bons Aug 27 '17 at 12:51
  • @PeterBons agree with you completely – Aydin Aug 27 '17 at 12:51