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"); 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 // fast forward execution in case parallelization is disabled
if (Control.DisableParallelization if (Control.DisableParallelization
|| ThreadQueue.ThreadCount <= 1 || ThreadQueue.ThreadCount <= 1
@ -144,6 +136,14 @@ namespace MathNet.Numerics.Threading
return; 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 enumerator = source.GetEnumerator();
var maxBlockSize = Control.InitialThreadBlockSize; var maxBlockSize = Control.InitialThreadBlockSize;
var scalingFactor = Control.BlockScalingFactor; var scalingFactor = Control.BlockScalingFactor;
@ -175,8 +175,11 @@ namespace MathNet.Numerics.Threading
maxBlockSize = Math.Min(Control.MaximumBlockSize, maxBlockSize * scalingFactor); maxBlockSize = Math.Min(Control.MaximumBlockSize, maxBlockSize * scalingFactor);
} }
WaitForTasksToComplete(tasks.ToArray()); if (tasks.Count > 0)
CollectExceptionsAndDisposeTasks(tasks); {
WaitForTasksToComplete(tasks.ToArray());
CollectExceptionsAndDisposeTasks(tasks);
}
} }
/// <summary> /// <summary>

120
src/UnitTests/ThreadingTests/ParallelForEachTests.cs

@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
{ {
[Test, ApartmentState(ApartmentState.MTA)] [Test, ApartmentState(ApartmentState.MTA)]
[Column( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)] [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 // ensure One-Per-Core
ThreadQueue.Start(Environment.ProcessorCount); ThreadQueue.Start(Environment.ProcessorCount);
@ -67,7 +67,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
[Test, ApartmentState(ApartmentState.STA)] [Test, ApartmentState(ApartmentState.STA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)] [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 // ensure One-Per-Core
ThreadQueue.Start(Environment.ProcessorCount); ThreadQueue.Start(Environment.ProcessorCount);
@ -95,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
[Test, ApartmentState(ApartmentState.MTA)] [Test, ApartmentState(ApartmentState.MTA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)] [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 // ensure Two-Per-Core
ThreadQueue.Start(2 * Environment.ProcessorCount); ThreadQueue.Start(2 * Environment.ProcessorCount);
@ -123,7 +123,7 @@ namespace MathNet.Numerics.UnitTests.ThreadingTests
[Test, ApartmentState(ApartmentState.STA)] [Test, ApartmentState(ApartmentState.STA)]
[Column(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1001)] [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 // ensure Two-Per-Core
ThreadQueue.Start(2 * Environment.ProcessorCount); 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)] [Test, ApartmentState(ApartmentState.MTA)]
public void DoesNotGetConfusedByMultipleStartShutdown() public void DoesNotGetConfusedByMultipleStartShutdown()
{ {

Loading…
Cancel
Save