bool ParallelComputeAverages(Numbers const &numbers, Averages &averages) { if (numbers.empty()) { return false; } // sort numbers for mode and median Numbers sorted = numbers; Averages avgResult; int modeResult; double medianResult; // sort numbers for median / mode tbb::parallel_sort(sorted); auto medianFunc = [&medianResult, &sorted]() { medianResult = ComputeMedian(sorted); }; auto avgFunc = [&avgResult, &numbers]() { auto grainSize = numbers.size() / thread::hardware_concurrency(); Averages avg{0, 0, 0, 0, 0, 0}; avgResult = tbb::parallel_reduce( Range(numbers.begin(), numbers.end(), grainSize), avg, CalcIntermediateAverages, AddIntermediateAverages); }; auto modeFunc = [&modeResult, &sorted]() { modeResult = ComputeMode(sorted); }; // invoke parallel execution of calculations tbb::parallel_invoke(avgFunc, modeFunc, medianFunc); // set result double size = (double) numbers.size(); averages.arithmeticMean = avgResult.arithmeticMean / size; averages.geometricMean = exp(avgResult.geometricMean / size); averages.harmonicMean = size / avgResult.harmonicMean; averages.quadraticMean = sqrt(avgResult.quadraticMean / size); averages.mode = modeResult; averages.median = medianResult; return true; }
void iterate() { printf("size = %d\n", numbers.size()); NumbersIter iter; for (iter = numbers.begin(); iter != numbers.end(); ++iter) { printf(" %d\n", *iter); } }