OpenMP
C++
algorithms
parallel computing
data processing

OpenMp C algorithms for min, max, median, average

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

OpenMP is useful for data-parallel numeric work because it can split independent loop iterations across CPU threads with relatively little code change. Operations such as minimum, maximum, and average are natural fits because they can be reduced from per-thread partial results. Median is different: it usually requires ordering information, so it is not a simple reduction problem.

Min, Max, and Average with Reductions

The simplest OpenMP wins come from reductions. Each thread computes a local result, and OpenMP combines them at the end of the loop.

cpp
1#include <iostream>
2#include <limits>
3#include <numeric>
4#include <vector>
5#include <omp.h>
6
7int main() {
8    std::vector<double> data {4.5, 9.1, 2.0, 7.3, 6.4, 1.2, 5.9};
9
10    double minVal = std::numeric_limits<double>::max();
11    double maxVal = std::numeric_limits<double>::lowest();
12    double sum = 0.0;
13
14    #pragma omp parallel for reduction(min:minVal) reduction(max:maxVal) reduction(+:sum)
15    for (int i = 0; i < static_cast<int>(data.size()); ++i) {
16        minVal = std::min(minVal, data[i]);
17        maxVal = std::max(maxVal, data[i]);
18        sum += data[i];
19    }
20
21    double average = sum / data.size();
22
23    std::cout << "min: " << minVal << '\n';
24    std::cout << "max: " << maxVal << '\n';
25    std::cout << "avg: " << average << '\n';
26}

This is a good OpenMP use case because every iteration is independent and the final combination rule is clear.

Why Median Is Different

Median is not just a sum-like reduction. To know the middle value, you need ordering information. The naïve approach is to sort the entire dataset, then pick the center.

cpp
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6    std::vector<double> data {4.5, 9.1, 2.0, 7.3, 6.4, 1.2, 5.9};
7
8    std::sort(data.begin(), data.end());
9
10    double median;
11    std::size_t n = data.size();
12    if (n % 2 == 0) {
13        median = (data[n / 2 - 1] + data[n / 2]) / 2.0;
14    } else {
15        median = data[n / 2];
16    }
17
18    std::cout << "median: " << median << '\n';
19}

You can parallelize sorting with specialized libraries or algorithms, but the median problem itself is fundamentally different from min, max, and sum. OpenMP alone does not turn median into a one-line reduction in the same way.

Use nth_element When Full Sorting Is Unnecessary

If you only need the median and not a fully sorted array, std::nth_element is often a better algorithmic choice than sorting everything.

cpp
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6    std::vector<int> data {9, 1, 7, 3, 5, 8, 2};
7    std::size_t mid = data.size() / 2;
8
9    std::nth_element(data.begin(), data.begin() + mid, data.end());
10    std::cout << "median: " << data[mid] << '\n';
11}

This example is not an OpenMP reduction, but it is often the right practical answer. Performance starts with choosing the correct algorithm, not only with adding threads.

When OpenMP Helps Most

OpenMP works best when the loop body is substantial enough to justify thread overhead. If the array is tiny, parallel reductions can be slower than a single-threaded loop. The cost of creating a team, synchronizing threads, and combining results is real.

That means you should use OpenMP when:

  • the dataset is large enough
  • each iteration is independent
  • the reduction or combination step is well-defined
  • memory bandwidth is not already the limiting factor

These conditions usually hold for large numeric arrays but less so for tiny collections.

Common Pitfalls

A common mistake is using shared variables inside a parallel loop without a reduction clause. That creates data races and makes the result nondeterministic.

Another mistake is parallelizing median as if it were the same kind of problem as average. Median needs order statistics, so a different algorithm is required.

Developers also often assume more threads always means more speed. For memory-bound loops, extra threads can saturate bandwidth and provide little benefit. Benchmark with realistic data sizes instead of relying on intuition.

Finally, be careful with floating-point sums. Parallel reduction order can differ from serial accumulation, so tiny numerical differences are normal. If strict reproducibility matters, you may need a more controlled summation strategy.

Summary

  • 'min, max, and average are natural OpenMP reduction problems.'
  • Median is different because it depends on ordering, not simple accumulation.
  • Use reduction clauses for thread-safe aggregation of independent loop results.
  • Consider nth_element when you need only the median and not a full sort.
  • Parallel code should still start with the right algorithm and real benchmarking.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.