/// <summary> /// Estimate Pi using TPL tasks /// </summary> /// <param name="maxRuntimeSeconds"></param> /// <param name="numberOfCores"></param> /// <remarks>This code only works with .NET 4.0 or newer</remarks> public void TaskParallelLibrary40(int maxRuntimeSeconds, int numberOfCores) { var inCircleDetails = new long[numberOfCores]; var iterationDetails = new long[numberOfCores]; var tasks = new Task[numberOfCores]; var runTimesByIndex = GetRunTimesByThread(numberOfCores, maxRuntimeSeconds); foreach (var item in runTimesByIndex) { // Must cache the values to avoid error "Access to modified closure" var procIndex = item.Key; var threadRuntime = item.Value; tasks[procIndex] = Task.Factory.StartNew(() => { var worker = new PiEstimateWorker(procIndex + 1, PreviewMode); worker.DoWork(threadRuntime); inCircleDetails[procIndex] = worker.HitsInCircle; iterationDetails[procIndex] = worker.TotalIterations; }); } Task.WaitAll(tasks); var inCircle = inCircleDetails.Sum(); var totalIterations = iterationDetails.Sum(); ComputeAndReportPi("TPL 4.0", inCircle, totalIterations, maxRuntimeSeconds); }
/// <summary> /// Estimate Pi using a parallel for loop /// </summary> /// <param name="maxRuntimeSeconds"></param> /// <param name="numberOfCores"></param> public void ParallellFor(int maxRuntimeSeconds, int numberOfCores) { long inCircle = 0; long totalIterations = 0; var threadNumber = 0; Parallel.For(0, numberOfCores, new ParallelOptions { MaxDegreeOfParallelism = numberOfCores }, i => { Interlocked.Add(ref threadNumber, 1); var worker = new PiEstimateWorker(threadNumber, PreviewMode); worker.DoWork(maxRuntimeSeconds); Interlocked.Add(ref inCircle, worker.HitsInCircle); Interlocked.Add(ref totalIterations, worker.TotalIterations); if (UseTieredRuntimes) { maxRuntimeSeconds = DecrementRuntime(maxRuntimeSeconds, numberOfCores); } }); ComputeAndReportPi("ParallelFor", inCircle, totalIterations, maxRuntimeSeconds); }
/// <summary> /// Estimate Pi using TPL tasks /// </summary> /// <param name="maxRuntimeSeconds"></param> /// <param name="numberOfCores"></param> /// <remarks>This code only works with .NET 4.5 or newer</remarks> public void TaskParallelLibrary45(int maxRuntimeSeconds, int numberOfCores) { var workers = new List <PiEstimateWorker>(); var workerTasks = new List <Task>(); var runTimesByIndex = GetRunTimesByThread(numberOfCores, maxRuntimeSeconds); foreach (var item in runTimesByIndex) { // Must cache the values to avoid error "Access to modified closure" var procIndex = item.Key; var threadRuntime = item.Value; var worker = new PiEstimateWorker(procIndex + 1, PreviewMode); workers.Add(worker); var workerTask = new Task(() => worker.DoWork(threadRuntime)); workerTasks.Add(workerTask); workerTask.Start(); } Task.WaitAll(workerTasks.ToArray()); var inCircle = workers.Sum(worker => worker.HitsInCircle); var totalIterations = workers.Sum(worker => worker.TotalIterations); ComputeAndReportPi("TPL 4.5", inCircle, totalIterations, maxRuntimeSeconds); }
/// <summary> /// Estimate Pi using a single thread /// </summary> /// <param name="maxRuntimeSeconds"></param> public void SerialCalculation(int maxRuntimeSeconds) { var worker = new PiEstimateWorker(1, PreviewMode); worker.DoWork(maxRuntimeSeconds); ComputeAndReportPi("SerialCalculation", worker.HitsInCircle, worker.TotalIterations, maxRuntimeSeconds); }