Friday, December 26, 2008

C# Parallel Foreach using Thread Pool



public void Foreach(T[] array, Action action)
{
int cpus = 2 * Environment.ProcessorCount;
int nitems = array.Length;
int chunk = nitems / cpus;
int counter = cpus;

using (AutoResetEvent signal = new AutoResetEvent(false))
{
for (int i = 1; i <= cpus; i++)
{
ThreadPool.QueueUserWorkItem(delegate(object o)
{
int unit = (int)o;

for (int j = (unit - 1) * chunk;
j < (unit == cpus ? nitems : unit * chunk);
j++)
{
action(array[j]);
}

if (Interlocked.Decrement(ref counter) == 0)
signal.Set();
}, i);
}

signal.WaitOne();
}
}





public void ForeachWithResults(T[] array, T1[] results, Action action)
{
int cpus = 2 * Environment.ProcessorCount;
int nitems = array.Length;
int chunk = nitems / cpus;
int counter = cpus;

using (AutoResetEvent signal = new AutoResetEvent(false))
{
for (int i = 1; i <= cpus; i++)
{
ThreadPool.QueueUserWorkItem(delegate(object o)
{
int unit = (int)o;

for (int j = (unit - 1) * chunk;
j < (unit == cpus ? nitems : unit * chunk);
j++)
{
action(j, array[j], results);
}

if (Interlocked.Decrement(ref counter) == 0)
signal.Set();
}, i);
}

signal.WaitOne();
}
}

1 comment:

  1. [...] In the last years I’ve always used a “parallel task” approach foreach loops that I’ve in the code, not always to speedup but even to clean-up the code. How to do it? Wrapping threads and Thread Pool like in this C# Parallel Forech Code. [...]

    ReplyDelete