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;
        }