From 4e9ed41576c32f82eb6780e7a9e8cec6623b7ab0 Mon Sep 17 00:00:00 2001 From: Marcus Cuda Date: Tue, 1 Sep 2009 17:48:56 +0800 Subject: [PATCH] localInit is now called once per thread rather than once per Parallel call Signed-off-by: Marcus Cuda --- src/Numerics/Threading/Parallel.cs | 40 +++++++++++++++++++----------- src/Numerics/Threading/TaskOfT.cs | 2 +- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/Numerics/Threading/Parallel.cs b/src/Numerics/Threading/Parallel.cs index ca888d94..1d710c90 100644 --- a/src/Numerics/Threading/Parallel.cs +++ b/src/Numerics/Threading/Parallel.cs @@ -139,19 +139,31 @@ namespace MathNet.Numerics.Threading var tasks = new Task[ThreadQueue.ThreadCount]; var size = count / tasks.Length; - var intial = localInit(); - // fast forward execution if it's only one or none items if (count <= 1) { if (count == 1) { - localFinally(body(fromInclusive, intial)); + localFinally(body(fromInclusive, localInit())); } return; } + // fast forward execution in case parallelization is disabled + if (Control.DisableParallelization + || ThreadQueue.ThreadCount <= 1 + || ThreadQueue.IsInWorkerThread) + { + var localresult = localInit(); + for (var i = fromInclusive; i < toExclusive; i++) + { + localresult = body(i, localresult); + } + localFinally(localresult); + return; + } + // partition the jobs into separate sets for each but the last worked thread for (var i = 0; i < tasks.Length - 1; i++) { @@ -160,15 +172,15 @@ namespace MathNet.Numerics.Threading tasks[i] = new Task( localData => { - var localresult = localData; + var localresult = (T)localData; for (var j = start; j < stop; j++) { - localresult = body(j, (T)localresult); + localresult = body(j, localresult); } - return (T)localresult; - }, - intial); + return localresult; + }, + localInit()); ThreadQueue.Enqueue(tasks[i]); } @@ -176,15 +188,15 @@ namespace MathNet.Numerics.Threading tasks[tasks.Length - 1] = new Task( localData => { - var localresult = localData; + var localresult = (T)localData; for (var i = fromInclusive + ((tasks.Length - 1) * size); i < toExclusive; i++) { - localresult = body(i, (T)localresult); + localresult = body(i, localresult); } - return (T)localresult; + return localresult; }, - intial); + localInit()); ThreadQueue.Enqueue(tasks[tasks.Length - 1]); if (tasks.Length <= 0) @@ -316,8 +328,6 @@ namespace MathNet.Numerics.Threading var maxBlockSize = IntialBlockSize; var tasks = new List>(); - var intial = localInit(); - var enumerator = source.GetEnumerator(); while (enumerator.MoveNext()) { @@ -343,7 +353,7 @@ namespace MathNet.Numerics.Threading return (TLocal)localresult; }, - intial); + localInit()); ThreadQueue.Enqueue(task); tasks.Add(task); diff --git a/src/Numerics/Threading/TaskOfT.cs b/src/Numerics/Threading/TaskOfT.cs index efdfaf1f..9638e874 100644 --- a/src/Numerics/Threading/TaskOfT.cs +++ b/src/Numerics/Threading/TaskOfT.cs @@ -42,7 +42,7 @@ namespace MathNet.Numerics.Threading private readonly Func _body; /// - /// Variable used to hold state information between interations. + /// Variable used to hold state information between iterations. /// private readonly object _state;