Browse Source

Parellel: found problem with tests, they were only testing the list version - added set versions

fixed bug when  no tasks were ran

Signed-off-by: Marcus Cuda <marcus@cuda.net>
la-knuth
Marcus Cuda 17 years ago
parent
commit
94af0578c8
  1. 23
      src/Numerics/Threading/Parallel.cs
  2. 120
      src/UnitTests/ThreadingTests/ParallelForEachTests.cs

23
src/Numerics/Threading/Parallel.cs

@ -123,14 +123,6 @@ namespace MathNet.Numerics.Threading
throw new ArgumentNullException("body");
}
// source is a IList, call For instead.
if (source is IList<T>)
{
var list = (IList<T>)source;
For(0, list.Count, i => body(list[i]));
return;
}
// fast forward execution in case parallelization is disabled
if (Control.DisableParallelization
|| ThreadQueue.ThreadCount <= 1
@ -144,6 +136,14 @@ namespace MathNet.Numerics.Threading
return;
}
// source is a IList, call For instead.
if (source is IList<T>)
{
var list = (IList<T>)source;
For(0, list.Count, i => body(list[i]));
return;
}
var enumerator = source.GetEnumerator();
var maxBlockSize = Control.InitialThreadBlockSize;
var scalingFactor = Control.BlockScalingFactor;
@ -175,8 +175,11 @@ namespace MathNet.Numerics.Threading
maxBlockSize = Math.Min(Control.MaximumBlockSize, maxBlockSize * scalingFactor);
}
WaitForTasksToComplete(tasks.ToArray());
CollectExceptionsAndDisposeTasks(tasks);
if (tasks.Count > 0)
{
WaitForTasksToComplete(tasks.ToArray());
CollectExceptionsAndDisposeTasks(tasks);
}
}
/// <summary>

120
src/UnitTests/ThreadingTests/ParallelForEachTests.cs

@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
{
[Test, ApartmentState(ApartmentState.MTA)]
[Column( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemOnceMTAOnePerCore(int count)
public void ParallelForEachInvokesEveryItemInListOnceMTAOnePerCore(int count)
{
// ensure One-Per-Core
ThreadQueue.Start(Environment.ProcessorCount);
@ -67,7 +67,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
[Test, ApartmentState(ApartmentState.STA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemOnceSTAOnePerCore(int count)
public void ParallelForEachInvokesEveryItemInListOnceSTAOnePerCore(int count)
{
// ensure One-Per-Core
ThreadQueue.Start(Environment.ProcessorCount);
@ -95,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
[Test, ApartmentState(ApartmentState.MTA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemOnceMTATwoPerCore(int count)
public void ParallelForEachInvokesEveryItemInListOnceMTATwoPerCore(int count)
{
// ensure Two-Per-Core
ThreadQueue.Start(2 * Environment.ProcessorCount);
@ -123,7 +123,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
[Test, ApartmentState(ApartmentState.STA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemOnceSTATwoPerCore(int count)
public void ParallelForEachInvokesEveryItemInListOnceSTATwoPerCore(int count)
{
// ensure Two-Per-Core
ThreadQueue.Start(2 * Environment.ProcessorCount);
@ -149,6 +149,118 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
}
}
[Test, ApartmentState(ApartmentState.MTA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemInSetOnceMTAOnePerCore(int count)
{
// ensure One-Per-Core
ThreadQueue.Start(Environment.ProcessorCount);
var items = new double[count];
var pairs = new HashSet<KeyValuePair<int, double>>();
for (var i = 0; i < items.Length; i++)
{
pairs.Add(new KeyValuePair<int, double>(i, i));
}
Parallel.ForEach(pairs, pair => items[pair.Key] = pair.Value);
Parallel.ForEach(pairs,
pair =>
{
items[pair.Key] = pair.Value + 1000;
}
);
for (int i = 0; i < items.Length; i++)
{
Assert.AreEqual(1000 + i, items[i], i.ToString());
}
}
[Test, ApartmentState(ApartmentState.STA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemInSetOnceSTAOnePerCore(int count)
{
// ensure One-Per-Core
ThreadQueue.Start(Environment.ProcessorCount);
var items = new double[count];
var pairs = new HashSet<KeyValuePair<int, double>>();
for (var i = 0; i < items.Length; i++)
{
pairs.Add(new KeyValuePair<int, double>(i, i));
}
Parallel.ForEach(pairs, pair => items[pair.Key] = pair.Value);
Parallel.ForEach(pairs,
pair =>
{
items[pair.Key] = pair.Value + 1000;
}
);
for (int i = 0; i < items.Length; i++)
{
Assert.AreEqual(1000 + i, items[i], i.ToString());
}
}
[Test, ApartmentState(ApartmentState.MTA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemInSetOnceMTATwoPerCore(int count)
{
// ensure Two-Per-Core
ThreadQueue.Start(2 * Environment.ProcessorCount);
var items = new double[count];
var pairs = new HashSet<KeyValuePair<int, double>>();
for (var i = 0; i < items.Length; i++)
{
pairs.Add(new KeyValuePair<int, double>(i, i));
}
Parallel.ForEach(pairs, pair => items[pair.Key] = pair.Value);
Parallel.ForEach(pairs,
pair =>
{
items[pair.Key] = pair.Value + 1000;
}
);
for (int i = 0; i < items.Length; i++)
{
Assert.AreEqual(1000 + i, items[i], i.ToString());
}
}
[Test, ApartmentState(ApartmentState.STA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)]
public void ParallelForEachInvokesEveryItemInSetOnceSTATwoPerCore(int count)
{
// ensure Two-Per-Core
ThreadQueue.Start(2 * Environment.ProcessorCount);
var items = new double[count];
var pairs = new HashSet<KeyValuePair<int, double>>();
for (var i = 0; i < items.Length; i++)
{
pairs.Add(new KeyValuePair<int, double>(i, i));
}
Parallel.ForEach(pairs, pair => items[pair.Key] = pair.Value);
Parallel.ForEach(pairs,
pair =>
{
items[pair.Key] = pair.Value + 1000;
}
);
for (int i = 0; i < items.Length; i++)
{
Assert.AreEqual(1000 + i, items[i], i.ToString());
}
}
[Test, ApartmentState(ApartmentState.MTA)]
public void DoesNotGetConfusedByMultipleStartShutdown()
{

Loading…
Cancel
Save