OpenMP, short for Open Multi-Processing, is an API for shared-memory parallel programming in C, C++, and Fortran. It was initially developed in 1997 by a consortium of hardware and software vendors to provide a standard for parallelizing code on multi-core systems. OpenMP is widely used in scientific computing, numerical simulations, image processing, and high-performance applications. Developers can access OpenMP through compiler support such as gcc, clang, or icc, with official specifications and guides available at OpenMP Official Specifications. Programs are enabled for parallel execution using compiler flags like -fopenmp and directives such as #pragma omp parallel.
OpenMP exists to simplify parallelization of code on shared-memory architectures by providing high-level constructs for threads, work distribution, and synchronization. Its design philosophy emphasizes readability, minimal intrusion into existing code, and portability across different compiler and hardware platforms. By providing standardized directives, OpenMP allows developers to parallelize loops, sections, and tasks efficiently without manually managing threads.
OpenMP: Parallel Loops
OpenMP enables parallel execution of loops using the #pragma omp parallel for directive, distributing iterations across threads.
#include <omp.h>
#include <stdio.h>
int main() {
int sum = 0;
#pragma omp parallel for reduction(+:sum)
for(int i = 1; i <= 10; i++) {
sum += i;
printf("Thread %d processing i=%d\n", omp_get_thread_num(), i);
}
printf("Total sum: %d\n", sum);
return 0;
}Parallel loops distribute work across available threads automatically. The reduction clause ensures correct aggregation of results without race conditions. This mechanism is similar to parallel reductions in Parallel Algorithms and complements other shared-memory programming approaches like MPI.
OpenMP: Sections and Tasks
OpenMP supports task-level parallelism through #pragma omp sections and #pragma omp task directives for independent workloads.
#pragma omp parallel
{
#pragma omp sections
{
#pragma omp section
printf("Section 1 executed by thread %d\n", omp_get_thread_num());
#pragma omp section
printf("Section 2 executed by thread %d\n", omp_get_thread_num());
}
#pragma omp single
{
#pragma omp task
printf("Task executed by thread %d\n", omp_get_thread_num());
}
}Sections allow parallel execution of independent code blocks, while tasks provide dynamic scheduling. These constructs enable flexible decomposition of workloads for improved performance, similar to task-based parallelism in Parallel Algorithms.
OpenMP: Synchronization
OpenMP provides constructs like #pragma omp critical, #pragma omp barrier, and #pragma omp atomic to manage shared data access.
int counter = 0;
#pragma omp parallel for
for(int i = 0; i < 100; i++) {
#pragma omp atomic
counter++;
}
printf("Final counter: %d\n", counter);Synchronization directives prevent data races and ensure consistency when threads access shared variables. They are essential for correctness and performance, complementing collective and point-to-point communication in MPI.
OpenMP is used in computational science, engineering simulations, and data processing applications to leverage multi-core CPUs efficiently. It integrates with other parallel frameworks such as MPI and high-level parallel libraries, providing a robust platform for scalable shared-memory parallel programming. For tutorials and official references, developers can consult OpenMP Resources and compiler documentation such as GCC or Clang manuals.