HipposWild
HipposWild

Reputation: 23

C# parallel for sharing internal variables

Hi I am working on the following code:

            Parallel.For(1, residRanges.Count, i =>
            {
                int count = 0;
                List<double> colAList = new List<double>();
                List<double> colBList = new List<double>();
                for (int x = 0; x < residErrorData.Count; x++)
                {
                    foreach (pricateConnection in residErrorData[x].connList)
                    {
                        if (residRanges[i].connection == nc.connection)
                        {
                            colAList.Add(residErrorData[x].residualError);
                            colBList.Add(nc.freq);
                            count = count + 1;
                        }
                    }
                }
                colA = new double[count];
                colB = new double[count];
                for (int j = 0; j < count; j++)
                {
                    colA[j] = colAList[j];
                    colB[j] = colBList[j];
                }

                residRangeError tempresid = residRanges[i];
                tempresid = fitResid(tempresid, colA, colB);                    

                residRanges[i] = tempresid;
                residRanges[i].n = count;                        
                }
            });

If I don't use the parallel class my values seem to be accurate however when i use the parallel class for some reason it mixes up the values for the colA and colB. It's mixing them between the threads. I'm fairly new to parallel processing but I've been looking around, and can't seem to find any solutions. Does anyone know why the program seems to be sharing variables between threads?

I know the code isn't ideal I've been trying different things to figure out what was going wrong. I'm not trying to necessarily optimize it at the moment so much as understand why the variables in the different loops aren't staying separate.

residRanges[] is a list of class items. The for loops using it seems to get the right values they just begin to mix up which values go where when run in Parallel.For.

Thanks for any help! I could really use it!

Upvotes: 2

Views: 488

Answers (1)

Dai
Dai

Reputation: 155443

(Reposting as an answer for sweet, sweet karma)

Your code looks as though colA and colB are declared outside the lambda's scope, which means the variable references could refer to different array objects as different threads run simultaneously (e.g. Thread 0 would change colA while Thread 1 is inside the for j < count loop.

Move the declarations of colA and colB to inside the lambda:

...
Double[] colA = new double[count];
Double[] colB = new double[count];
for (int j = 0; j < count; j++)
...

However I see that you don't actually do anything useful with colA and colB other than using them as a value holder for your fitResid function, you can simplify this by:

  1. Change your fitResid function signature to accept IList<Double> instead of Double[]
  2. Change your fitResid function call to pass in colAList and colBList in respectively, which will speed up your code by eliminating the unnecessary copying and memory allocation:

    ...             
    residRanges[i] = fitResid( residRanges[i], colAList, colBList );
    residRanges[i].n = count;        
    ...
    

Upvotes: 3

Related Questions