Self-Assessment Quiz: OpenMP

Twenty questions to confirm you can scope a parallel region correctly and spot a race before it costs you a run. Aim for 16 or more. Answers and a topic map are at the end — try the whole quiz first.


Question 1

In the fork–join model, at !$omp end parallel the program: - A. Terminates - B. Joins the team back to the single master thread and continues serially - C. Forks a second team - D. Waits for the user to press a key

Question 2

Which flag enables OpenMP in gfortran? - A. -O3 - B. -fcoarray=single - C. -fopenmp - D. -parallel

Question 3

Compiled without the OpenMP flag, a source file full of !$omp directives: - A. Fails to compile - B. Compiles and runs as a correct serial program (the directives are comments) - C. Runs in parallel anyway - D. Deletes the directives from the file

Question 4

omp_get_thread_num() returns, for the master thread: - A. 1 - B. The total number of threads - C. 0 - D. A random integer

Question 5

The !$omp do construct distributes a loop's iterations so that each iteration runs: - A. Once per thread (so the loop body executes team-size times as often) - B. Exactly once, on one thread of the team - C. Only on the master thread - D. Twice, for error checking

Question 6

True or false, with one sentence of justification: "A !$omp do directive placed outside any parallel region still runs the loop in parallel."

Question 7

The default data-sharing attribute that OpenMP assigns to a variable you forget to scope is: - A. private - B. firstprivate - C. shared - D. reduction

Question 8

The purpose of the default(none) clause is to: - A. Disable all parallelism - B. Force you to give every variable in the region an explicit data-sharing attribute - C. Make every variable private - D. Turn off scheduling

Question 9

Summing an array with a shared accumulator and no reduction (s = s + x(i)) across a team produces: - A. The correct sum, always - B. A compiler error - C. A wrong sum that varies from run to run (a data race) - D. A sum that is always exactly zero

Question 10

Each thread's private copy of the accumulator in reduction(+:s) is initialized to: - A. The value s had before the region - B. 1 - C. 0 (the identity for +) - D. huge(s)

Question 11

The difference between private(x) and firstprivate(x) is that firstprivate: - A. Makes x shared - B. Initializes each thread's copy to x's pre-region value - C. Copies the last iteration's value back out - D. Is only legal for arrays

Question 12

Which loop iteration variable is made private automatically, without you listing it? - A. Every variable in the loop body - B. The iteration variable of the loop associated with !$omp do (the outer index) - C. All inner loop indices - D. None; you must list every index

Question 13

For combining per-thread partial results, the fastest-to-slowest ranking of mechanisms is: - A. critical > atomic > reduction - B. reduction > atomic > critical - C. atomic > reduction > critical - D. They are all equally fast

Question 14

schedule(static) is the right choice when: - A. Iterations vary wildly in cost - B. Every iteration costs about the same (uniform work) and you want reproducible, low-overhead assignment - C. You need dynamic load balancing - D. The loop has an unknown trip count

Question 15

schedule(dynamic) earns its extra overhead when: - A. The work per iteration is uniform - B. The work per iteration is uneven, so idle threads can grab more chunks - C. You have only one thread - D. You want deterministic iteration assignment

Question 16

False sharing is: - A. Two threads correctly sharing read-only data - B. Different threads writing different variables that land on the same cache line, causing coherence traffic - C. A compiler error about shared clauses - D. A synonym for a data race

Question 17

True or false, with justification: "The OpenMP heat solver can give a slightly different temperature field than the serial solver, because the threads run in a nondeterministic order."

Question 18

!$omp simd provides parallelism by: - A. Splitting iterations across threads - B. Vectorizing a loop so one core processes several elements per instruction - C. Launching a GPU kernel - D. Creating a new team

Question 19

You would reach for !$omp task` instead of `!$omp do when: - A. The loop has a known, countable trip count - B. The work is irregular or recursive (tree/list traversal) and cannot be written as a counted loop - C. You want the fastest possible array sweep - D. You need a reduction

Question 20

What does this print, and what part is nondeterministic?

!$omp parallel do default(none) private(i) reduction(+:s)
do i = 1, 4
  s = s + real(i, dp)      ! s initialized to 0.0_dp before the region
end do
!$omp end parallel do
print '(f6.1)', s
  • A. 10.0, and nothing is nondeterministic about the printed value
  • B. A different number each run
  • C. 0.0 always
  • D. It fails to compile

Answer Key

Q Ans Why
1 B end parallel joins the team; the master continues alone, serially.
2 C -fopenmp enables the directives and links the runtime.
3 B !$omp lines are comments without the flag — the same source is correct serial code.
4 C The master is always thread 0.
5 B Work sharing partitions iterations: each runs once, on one thread.
6 False With no team to share among, !$omp do just runs serially on the master — no parallelism.
7 C The dangerous default is shared, which races on anything you write.
8 B default(none) forces an explicit attribute for every variable.
9 C Unsynchronized read–add–write of a shared scalar is a data race: wrong and run-to-run-varying.
10 C Each private copy starts at the operator's identity — 0 for +.
11 B firstprivate initializes each copy to the pre-region value; plain private is uninitialized.
12 B Only the !$omp do loop's own (outer) index is auto-private; inner indices are your job.
13 B reduction (no contention) > atomic (one cheap update) > critical (a general lock).
14 B static is cheapest and reproducible for uniform work.
15 B dynamic self-balances uneven work, repaying its hand-out overhead.
16 B False sharing = different variables on one cache line → coherence ping-pong; correct but slow.
17 False The result is deterministic and must match the serial solver; only the schedule is nondeterministic.
18 B simd vectorizes within a thread (multiple data per instruction).
19 B task is for irregular/recursive work a counted loop can't express.
20 A 1+2+3+4 = 10.0; the reduction makes the result deterministic. Only the schedule (invisible here) varies.

Topics to review by question

  • Q1–4 → §33.1 (fork–join, the flag, thread ids).
  • Q5–6, 14–15 → §33.2 and §33.4 (work sharing and scheduling).
  • Q7–12, 20 → §33.3 (data scoping, default(none), reduction, firstprivate).
  • Q9, 13, 16–17 → §33.3–33.5 (races, the synchronization ranking, false sharing, determinism).
  • Q18–19 → §33.5 (SIMD and tasks).

Scored below 16? Reread §33.3 first — data scoping is where most of these questions, and most real OpenMP bugs, live.