Lec7 Parallel Programming
Lec7 Parallel Programming
❑ Try 1:
➢ We will use a threads programming mod
a dedicated processor, and the threads
through shared memory (including the cac
➢ Thus, each thread has its own process s
and file state.
➢ To implement a parallel version of the p
array so that each thread is responsible fo
of the array, where t is the number of thre
➢ Assume, t = 4 threads and length = 16.
Parallelism Using Multiple I
Languages
Compilers
✓C ✓ GCC (GNU
✓C++ Compiler Collection)
✓ Clang/LLVM
Pla
✓Fortran ✓ Intel oneAPI ✓ Lin
compilers ✓ Win
✓ Microsoft Visual ✓ ma
C++ (partial support) (lim
by
Why Use Open
❑ Easy to learn (directive-based)
❑ Portable across platforms
❑ Scales with available CPU cores
❑ Reduces development time compared to ma
Application
❑ Scientific Computing: Simulations (physics, ch
methods and matrix computations
❑ Engineering: Finite element analysis (FEA) ; Com
❑ Data Processing: Large-scale data analysis; Paralle
❑ Machine Learning & AI: Speeding up training and
❑ Image & Signal Processing: Video encoding/decod
What OpenMP
❑ At its core, OpenMP helps you paralle
that can run concurrently. Instead of m
add directives like:
#pragma omp <spe
❑ The compiler and runtime handle thre
and workload distribution.
❑ An OpenMP-compliant compiler will
generate appropriate multithreaded cod
❑ Compilers that don’t accept OpenMP
yielding standard sequential execution.
OpenMP Prag
❑ OpenMP provides several directives (pra
split across threads.
1. parallel — Create Threads: This is the ba
threads. Example
#pragma omp parallel [clause...] #pragma
{ {
// parallel code printf("
} }
Use Case:
▪ Initialization
▪ File I/O
▪ Printing results
Use Case:
▪ Protect shared resources
▪ Avoid race conditions
Use Case:
▪ Faster
▪ Limited to simple expressions
Example:
#pragma omp parallel private(x) shared
OpenMP Prag
❑ Exercise: Determine the output of the
❑ a → shared
▪ One single shared variable i
▪ All threads update the same a i
▪ Race condition (no synchronization) i
❑ b → firstprivate #
▪ Each thread gets its own copy of b
▪ Initialized to 2 f
▪ Changes are local only
▪ Final b outside loop remains 2
❑ c → private + lastprivate
▪ Each thread has its own c
▪ During loop: private values used
▪ After loop: value from logically last iteration (i = 3) is
copied back
Inside Loop Output: Outside Loop Output: }
02 13 p
3
1 3 Or 0 2 Or Many others 2
p
24 3 5 p
<undefined value>
35 24
OpenMP Exam
❑ Example: Summation
#pragma omp parallel for: #include <o
➢ Two directives combined: #include <st
▪ parallel → creates a team of threads
▪ for → divides loop iterations among those int main() {
threads int sum =
reduction(+:sum):
➢ If multiple threads do: sum += i; they may #pragma
overwrite each other → incorrect result. for (int i =
➢ What reduction does: sum +=
▪ Each thread gets its own private copy of }
sum
▪ Each thread computes partial results printf("Su
▪ At the end → all partial sums are combined return 0;
using + }
Exam
schedule(static): controls how loop iterations are Threa
assigned to threads. Threa
▪ Iterations are divided equally at compile/start time. Lo
▪ Each thread gets a fixed chunks. Be
OpenMP Exam
❑ Example: Counting 3s in an array
int count3s(int array[], int length)
{
int i, count, count_p;
count = 0;
#pragma omp parallel shared(array, count, length) private(count_p)
{
count_p = 0;
#pragma omp for private(i)
for (i = 0; i < length; i++)
{
if (array[i] == 3)
{
count_p++;
}
}
OpenMP Exam
❑ Example: Counting 3s in an array
u = dequeue(Q) M
B
for each v in adj[u] {
q
if (visited[v] == false) {
visited[v] = true F
enqueue(Q, v)
}
n
} b
}
OpenMP Exam
❑ Example: Classic BFS Traversal Algorithm
S ❑
/ \
A B
/ \ / \
C D E F
BFS Order: S → A, B → C, D, E, F
❑
❑ A queue in BFS ensures level order
traversal, meaning:
✓ All nodes at distance 1 from the source ❑
are processed before distance 2
✓ All nodes at distance 2 are processed
before distance 3, and so on
❑ The queue enforces this rule: Don’t move to the next lev
OpenMP Exam
❑ Example: Classic BFS Traversal Algorithm
❖ Instead of thinking, Process ONE node →
❖ Think: Process ALL nodes at current leve
❖ Rewriting the sequential BFS (level-wise):
Queue (Sequential
Aspect Frontier (Parallel BF
BFS)
Structure FIFO (first-in-first-out) Unordered set/list
Processing
One node at a time Many nodes at once
style
Dynamic (while queue
Control flow Level-by-level (bulk proces
not empty)
Ordering Strict order maintained Order doesn’t matter within
Synchronizat
Minimal Required
ion
OpenMP Exam
❑ Example: Classic BFS Traversal Algorithm
❖ Nodes in the same frontier:
✓ Are independent
✓ No ordering dependency
✓ Can be processed in parallel
u = frontier[i]
if (visited[v] == false) {
// synchronization needed here
}
}
}
OpenMP Exam
❑ Example: Classic BFS Traversal Algorithm
// BFS data
visited[N] = {false
frontier[]
next_frontier[]
OpenMP Exam
❑ Example: Classic BFS Traversal Algorithm
❖ Try 1: Every time a thread finds a new node → it
visited[source] = true
2
#pragma omp parallel for
1 frontier = {source}
for (i = 0; i < [Link]; i+
while (frontier not empty) {
u = frontier[i]
next_size = 0
for each v in adj[u] {
} if (visited[v] == false) {
3 }
}
#pragma omp critical
} {
} if (visited[v] == fal
visited[v] = true
frontier = next_frontier next_frontier[ne
} next_size++
OpenMP Exam
❑ Example: Classic BFS Traversal Algorithm
❖ Try 2: Avoid full lock; Use atomic to safely grab
visited[source] = true
2
#pragma omp parallel for
1 frontier = {source}
for (i = 0; i < [Link]; i++)
while (frontier not empty) { u = frontier[i]
for each v in adj[u] {
next_size = 0
if (visited[v] == false) {
// try to mark visited saf
bool was_visited
❑ Better but still contention #pragma omp atomic ca
on: {
o visited[v] was_visited = visite
o next_size visited[v] = true
❖ Locking reduced, but }
didn’t eliminate contention if (was_visited == false
int pos
OpenMP Exam
❑ Example: Classic BFS Traversal Algorithm
❖ Try 3: Use local buffers + critical outside; Eac
results once per thread (not per edge)
3
for each v in adj[u] {
1 visited[source] = true
frontier = {source} if (visited[v] == false
// try to mark visited
while (frontier not empty) { bool was_visited
#pragma omp atom
next_size = 0 {
was_visited =
2 }
visited[v] = tr
ODD 2 5 3 4 6
EVEN 2 3 5 4 6
ODD 2 3 4 5 6
EVEN 2 3 4 5 6
ODD 2 3 4 5 6
OpenMP Exam
❑ Example: Classic Bubble Sort Algorithm [P
1
for (phase = 0; phase < n; phase++) 2
{
if (phase % 2 == 0) else
{ {
// even phase // odd phase
#pragma omp parallel for #pragma omp parallel f
for (i = 0; i < n-1; i += 2) for (i = 1; i < n-1; i +=
{ {
if (A[i] > A[i+1]) if (A[i] > A[i+1])
{ {
swap(A[i], A[i+1]) swap(A[i], A[i+1]
} }
} }
} }
}
OpenMP Exam
❑ Example: Quick Sort Algorithm [Paradigm
➢In quickso
QuickSort(A, low, high) Left s
{ Right
if (low < high) ➢For exam
{ pivot = 5
p = Partition(A, low, high)
where th
QuickSort(A, low, p-1) independe
QuickSort(A, p+1, high) parallelism
} ➢ Sequentia
} THEN so
thinks sor
OpenMP Exam
❑ Example: Quick Sort Algorithm [Paradigm
1 ➢ Partition
ParallelQuickSort(A, low, high) regions.
{ ➢ Independe
if (low < high) ➢ Threads p
{
p = Partition(A, low, high)
➢ Much less