C# Parallel.For
C# Parallel.For
Hey guys. I decided to use Parallel.For for one of my for loops to make it faster, but for some reason once I hook up the Parallel.For, I get a System.ArgumentException error cast and it says the Source array was not long enough, even though it works perfectly fine for a normal for loop. None of that code changed.
- a_bertrand
- Posts: 1536
- Joined: Mon Feb 25, 2013 1:46 pm
Re: C# Parallel.For
You should provide us the code to try to help you. Just like that it's impossible to say what's going on.
Creator of Dot World Maker
Mad programmer and annoying composer
Mad programmer and annoying composer
Re: C# Parallel.For
Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace EconomicSimulator
{
class Citizen
{
public static int Population;
public static List<long> citizenList = new List<long>();
public static void Populate()
{
long income;
Random rnd = new Random();
Population = rnd.Next(17800000, 47800000); //Creating the population, some # between those numbers
Parallel.For(0, Population, i => //Loop through the population
{
double incomeChance = (rnd.Next(0, 1200000)); //Figure out which income bracket said 'person' is in
if (incomeChance <= 1)
{
income = Math.Abs(10000000 * rnd.Next(10000, 80000));
citizenList.Add(income);
// Over $10,000,000
}
else if (incomeChance <= 2)
{
income = Math.Abs(1000 * rnd.Next(5000, 10000));
citizenList.Add(income);
// $5,000,000 to $10,000,000
}
else if (incomeChance > 3 && incomeChance <= 7)
{
income = Math.Abs(1000 * rnd.Next(1500, 2000));
citizenList.Add(income);
// $1,500,000 to $2,000,000
}
else if (incomeChance > 7 && incomeChance <= 30)
{
income = Math.Abs(1000 * rnd.Next(2000, 5000));
citizenList.Add(income);
// $2,000,000 to $5,000,000
}
else if (incomeChance > 30 && incomeChance <= 86)
{
income = Math.Abs(1000 * rnd.Next(1000, 1500));
citizenList.Add(income);
// $1,000,000 to $1,500,000
}
else if (incomeChance > 86 && incomeChance <= 136)
{
income = Math.Abs(100 * rnd.Next(5000, 10000));
citizenList.Add(income);
// $500,000 to $1,000,000
}
else if (incomeChance > 136 && incomeChance <= 256)
{
income = Math.Abs(100 * rnd.Next(2000, 5000));
citizenList.Add(income);
// $200,000 to $500,000
}
else if (incomeChance > 256 && incomeChance <= 10606)
{
income = Math.Abs(10 * rnd.Next(2500, 3000));
citizenList.Add(income);
// $25,000 to $30,000
}
else if (incomeChance > 10606 && incomeChance <= 50606)
{
income = Math.Abs(10 * rnd.Next(2000, 2500));
citizenList.Add(income);
// $20,000 to $25,000
}
else if (incomeChance > 50606 && incomeChance <= 100606)
{
income = Math.Abs(rnd.Next(1, 5000));
citizenList.Add(income);
// $1 to $5,000
}
else if (incomeChance > 100606 && incomeChance <= 280606)
{
income = Math.Abs(10 * rnd.Next(4000, 5000));
citizenList.Add(income);
// $40,000 to $50,000
}
else if (incomeChance > 280606 && incomeChance <= 345606)
{
income = Math.Abs(10 * rnd.Next(7500, 10000));
citizenList.Add(income);
// $75,000 to $100,000
}
else if (incomeChance > 345606 && incomeChance <= 426606)
{
income = Math.Abs(10 * rnd.Next(1500, 2000));
citizenList.Add(income);
// $15,000 to $20,000
}
else if (incomeChance > 426006 && incomeChance <= 621006)
{
income = Math.Abs(rnd.Next(5000, 10000));
citizenList.Add(income);
// $5,000 to $10,000
}
else if (incomeChance > 621006 && incomeChance <= 710006)
{
income = Math.Abs(10 * rnd.Next(1000, 1500));
citizenList.Add(income);
// $10,000 to $15,000
}
else if (incomeChance > 710006 && incomeChance <= 780006)
{
income = Math.Abs(10 * rnd.Next(3000, 4000));
citizenList.Add(income);
// $30,000 to $40,000
}
else if (incomeChance > 780006 && incomeChance <= 800006)
{
income = Math.Abs(100 * rnd.Next(1000, 2000));
citizenList.Add(income);
// $100,000 to $200,000
}
else if (incomeChance > 800006)
{
income = Math.Abs(10 * rnd.Next(5000, 7500));
citizenList.Add(income);
// $50,000 to $75,000
}
});
}
}
}
- Jackolantern
- Posts: 10891
- Joined: Wed Jul 01, 2009 11:00 pm
Re: C# Parallel.For
I am not that familiar with the TPL in .NET, but does this require synchronization or some other type of thread-safety on the citizenList, Alan? If so, Xaos, you may want to consider switching to one of the ready-made thread-safe collections. Unchecked multithreading can cause all kinds of headaches with collections, such as doubling values, missing values, etc.
Also, Xaos, have you actually checked that this FOR loop is causing performance problems? I do realize it is running millions of times, but that may actually finish at a decent rate since little work is being done inside of it. It is generally a best practice to not start worrying about optimization until you are sure there is a problem. If it is completing in a half a second or so, I would see little point in investing it making it concurrent.
Also, Xaos, have you actually checked that this FOR loop is causing performance problems? I do realize it is running millions of times, but that may actually finish at a decent rate since little work is being done inside of it. It is generally a best practice to not start worrying about optimization until you are sure there is a problem. If it is completing in a half a second or so, I would see little point in investing it making it concurrent.
The indelible lord of tl;dr
Re: C# Parallel.For
Well I was hoping that this would work so I could see if this could make it faster. But ill check into thoee you linker.
- a_bertrand
- Posts: 1536
- Joined: Mon Feb 25, 2013 1:46 pm
Re: C# Parallel.For
Indeed, lists are not thread safe and here this code will access the list from multiple threads at the same time. Either lock every access of the list, or use a thread safe collection. You will not be 100% pleased by those collections however as they are not the same as the non thread safe one.
Creator of Dot World Maker
Mad programmer and annoying composer
Mad programmer and annoying composer
- Jackolantern
- Posts: 10891
- Joined: Wed Jul 01, 2009 11:00 pm
Re: C# Parallel.For
You will also notice quite a large step backwards in performance back towards the sequential access. Almost all of your code inside the parallel for loop would be considered critical, so a ton of that is going to end up becoming sequential to maintain locks.
The indelible lord of tl;dr
Re: C# Parallel.For
Ohh, gotcha guys. How do you guys recommend optimizing? I'm basically running this for loop, finding the mean, finding the median, then taking a % of each value in an array (from the for loop) and taking a %, adding it to anohter value and changing it in the array.
- Jackolantern
- Posts: 10891
- Joined: Wed Jul 01, 2009 11:00 pm
Re: C# Parallel.For
About 20-30 minutes for a simulation of 17.8 million - 47.8 million.