public static PerformanceResult RunConcurrentPerformanceTest(int numIterations, int degreeParallelism,
            Action operation)
        {
            int i;
            var taskList = new Task<PerformanceResult>[degreeParallelism];
            long startTime = HiResTimer.Ticks;
            int subIterations = numIterations/degreeParallelism;

            for (i = 0; i < degreeParallelism; i++)
            {
                var t = new Task<PerformanceResult>(() => RunPerformanceTest(subIterations, operation, true));
                taskList[i] = t;
            }

            for (i = 0; i < degreeParallelism; i++) taskList[i].Start();

            Task.WaitAll(taskList);
            long stopTime = HiResTimer.Ticks;

            var rawData = new List<double>();

            for (i = 0; i < degreeParallelism; i++)
            {
                rawData.AddRange(taskList[i].Result.DescriptiveResult.RawData);
            }

            var desc = new DescriptiveAnalysis(rawData);
            desc.Analyze(false);
            desc.AnalyzeHistogram(cHistogramBuckets);

            var res = new PerformanceResult
            {
                IsValid = true,
                Iterations = taskList.Sum(p => p.Result.Iterations),
                DegreeOfParallelism = degreeParallelism,
                TotalMilliseconds = ConvertToMs(startTime, stopTime),
                TotalSeconds = ConvertToSeconds(startTime, stopTime),
                TotalTicks = stopTime - startTime,
                DescriptiveResult = desc.Result
            };

            for (i = 0; i < degreeParallelism; i++) taskList[i].Dispose();

            return res;
        }
        public static PerformanceResult RunPerformanceTest(int numIterations, Func<bool> operation,
            bool isParallel = false)
        {
            bool isResultValid = true;
            var measures = new List<double>(numIterations);

            // grab the start time
            long startTime = HiResTimer.Ticks;

            // Same operation as the functional test, we just
            // do a lot of them.
            for (int i = 0; ((i < numIterations) && (isResultValid)); i++)
            {
                long aStart = HiResTimer.Ticks;
                isResultValid &= (operation());
                long aStop = HiResTimer.Ticks;
                if (isResultValid) measures.Add(ConvertToMs(aStart, aStop));
            }

            // grab the stop time
            long stopTime = HiResTimer.Ticks;

            var descriptive = new DescriptiveAnalysis(measures);
            descriptive.Analyze(isParallel);
            if (!isParallel) descriptive.AnalyzeHistogram(cHistogramBuckets);

            // If they all worked, we can report a valid result.
            // If they didn't then we call the perf test inconclusive.
            return new PerformanceResult
                   {
                       IsValid = isResultValid,
                       TotalSeconds = ConvertToSeconds(startTime, stopTime),
                       TotalMilliseconds = ConvertToMs(startTime, stopTime),
                       TotalTicks = (stopTime - startTime),
                       DescriptiveResult = descriptive.Result
                   };
        }
        public static PerformanceResult RunConcurrentPerformanceTest(int numIterations, int degreeParallelism,
            Func<bool> operation)
        {
            int i;
            var taskList = new Task<PerformanceResult>[degreeParallelism];

            int subIterations = numIterations/degreeParallelism;

            for (i = 0; i < degreeParallelism; i++)
            {
                var t = new Task<PerformanceResult>(() => RunPerformanceTest(subIterations, operation, true));
                taskList[i] = t;
            }

            for (i = 0; i < degreeParallelism; i++) taskList[i].Start();

            Task.WaitAll(taskList);

            var rawData = new List<double>();
            bool valid = true;

            for (i = 0; i < degreeParallelism; i++)
            {
                valid &= taskList[i].Result.IsValid;
                rawData.AddRange(taskList[i].Result.DescriptiveResult.RawData);
            }

            var desc = new DescriptiveAnalysis(rawData);
            desc.Analyze(false);
            desc.AnalyzeHistogram(cHistogramBuckets);

            var res = new PerformanceResult
                      {
                          IsValid = valid,
                          TotalMilliseconds = taskList.Max(p => p.Result.TotalMilliseconds),
                          TotalSeconds = taskList.Max(p => p.Result.TotalSeconds),
                          TotalTicks = taskList.Max(p => p.Result.TotalTicks),
                          DescriptiveResult = desc.Result
                      };

            for (i = 0; i < degreeParallelism; i++) taskList[i].Dispose();

            return res;
        }