Skip to content

sneakyjbras/omp-experiments

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

omp-experiments (Manjaro)

Small C++23 + OpenMP experiments repo with two executables:

  • omp_1: OpenMP scheduling / barrier behavior demos (omp for, nowait, manual partitioning)
  • omp_2: 1D stencil-style update showing:
    • a deliberately racy in-place OpenMP version (nondeterministic),
    • two correct deterministic versions: next+swap and ghost in-place.

Requirements (Manjaro)

Install toolchain + build tools:

Option A (recommended): GCC toolchain

sudo pacman -S --needed base-devel gcc make

Option B: Clang toolchain

sudo pacman -S --needed base-devel clang make
# OpenMP runtime for clang (often needed)
sudo pacman -S --needed libomp

Note: With GCC, OpenMP support is typically available out of the box via -fopenmp. With Clang, you may need libomp installed (and still compile with -fopenmp).

Build

make -j

Useful overrides:

make -j CXX=clang++
make -j CXXFLAGS='-O3 -std=c++23 -Wall -Wextra -Wpedantic -Iinclude -fopenmp'

Clean:

make clean

Run

omp_1

./omp_1

Control threads:

export OMP_NUM_THREADS=8
./omp_1

omp_2

Usage:

./omp_2 [size] [iters] [print]
# size  default: 256
# iters default: 64
# print default: 1 (set 0 to disable output)

Examples:

# Compare all variants side-by-side (stdout) + timings (stderr)
OMP_NUM_THREADS=8 ./omp_2 256 64 1

# Benchmark-only (recommended): disable printing
OMP_NUM_THREADS=8 ./omp_2 50000000 20 0

What omp_2 computes

Each iteration updates:

  • for i = 0..size-2: v[i] = (v[i] + v[i+1]) / 2
  • v[size-1] is unchanged

This is a loop-carried dependence (each i depends on the old value of i+1).

The 3 variants in omp_2

  1. WRONG in-place (racy under OpenMP)
    Parallelizes the in-place loop directly. Thread i may read v[i+1] after thread i+1 already overwrote it, so you mix “old” and “new” values depending on timing. Result: nondeterministic output.

  2. RIGHT next+swap (OpenMP-safe)
    Reads from v and writes to a separate next buffer, then swaps buffers. swap itself is O(1); the real work is the per-element reads/writes. Deterministic.

  3. RIGHT ghost in-place (OpenMP-safe)
    Each thread updates a contiguous chunk in-place, but caches a single “ghost” boundary value (old v[end]) before any writes, with barriers to enforce correctness. Deterministic.

Output & timing

  • When print=1, omp_2 prints the three outputs side-by-side to stdout.
  • It always prints timings to stderr:
Time WRONG in-place       : ... s
Time RIGHT next+swap      : ... s
Time RIGHT ghost in-place : ... s

Tip: for benchmarking, disable printing and redirect stdout:

OMP_NUM_THREADS=8 ./omp_2 50000000 20 0 > /dev/null

Project layout

include/demo/
  argparse.hpp
  omp1.hpp
  omp2.hpp
  omp_utils.hpp
src/
  argparse.cpp
  omp1.cpp
  omp_1_main.cpp
  omp2.cpp
  omp_2_main.cpp
Makefile

About

Collection of OpenMP experiments exploring parallel patterns, synchronization, reductions, scheduling strategies, and performance trade-offs in shared-memory programs.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors