DSA

Part 19 — Parallel Computing

A Staff-level coding interview guide to parallelism, concurrency, synchronization, parallel reduction, scalability, and Python reasoning.

Deepak Mishra12 min read


Modern software systems rarely depend on a single processor executing every operation sequentially.

As workloads grow, we increasingly need to reason about:

Parallel execution
Concurrency
Synchronization
Shared state
Work partitioning
Load balancing
Distributed computation

For a Staff/Principal engineer, the important question is not simply:

“Can I run two things at the same time?”

It is:

“Can I decompose the workload safely, minimize dependencies, control synchronization, and explain the performance trade-offs?”

The available interview material contains Staff-level discussion connecting associative operations such as XOR reduction to parallel reduction, MapReduce, GPU kernels, and distributed aggregation. It also places the advanced algorithmic material around Parts/Chapters 15–18.


1. Sequential vs Parallel Execution

Suppose we have four independent operations:

A = 10 ms
B = 20 ms
C = 15 ms
D = 30 ms

Sequential execution is approximately:

T_sequential ≈ A + B + C + D

So:

≈ 75 ms

If the operations are independent and can execute simultaneously:

T_parallel ≈ max(A, B, C, D)

Ideally:

≈ 30 ms

The key observation is:

Sequential
→ sum of work

Parallel
→ critical path

2. Not Everything Can Be Parallelized

Consider:

A → B → C → D

B depends on A.

C depends on B.

D depends on C.

These operations form a dependency chain.

Even with many processors:

A

B

C

D

must remain sequential.

Parallelism is limited by dependencies.


3. Dependency Graph

A useful way to reason about parallel computation is with a dependency graph:

        A
      /   \
     B     C
      \   /
        D

B and C can potentially execute in parallel:

A

┌───────┐
B       C
└───┬───┘

    D

This is the basic structure behind many workflow engines and distributed systems.


4. Work vs Critical Path

Two important quantities are:

Total work

and:

Critical-path length

Total work represents the amount of computation.

Critical path represents the longest dependency chain.

Adding processors can reduce execution time only until dependency constraints dominate.


5. Amdahl’s Law

Suppose:

90% of the workload

can be parallelized.

Then:

10%

remains sequential.

With infinitely many processors:

Speedup_max = 1 / 0.10 = 10

The lesson is:

A small sequential fraction can place a hard limit on total speedup.


6. Parallelism Is Not Free

Real systems also pay for:

thread creation
scheduling
communication
synchronization
memory contention
cache misses
serialization
load imbalance

Therefore:

Useful parallelism
=
parallel work
− coordination overhead

7. Embarrassingly Parallel Workloads

Some problems are almost perfectly parallel.

Example:

Process 1 million independent images

Each image can be processed independently:

Image 1 → Worker 1
Image 2 → Worker 2
Image 3 → Worker 3
...

Examples include:

batch inference
image processing
Monte Carlo simulation
independent transformations
large-scale feature computation

8. Data Parallelism

Data parallelism applies the same operation to different pieces of data.

Dataset
├── Partition 1
├── Partition 2
├── Partition 3
└── Partition 4

Each worker executes:

same function
+
different data

Conceptually:

              Dataset

       ┌─────────┼─────────┐
       ↓         ↓         ↓
    Worker 1  Worker 2  Worker 3
       ↓         ↓         ↓
       Result    Result    Result
              \   |   /
                Merge

9. Task Parallelism

Task parallelism executes different operations concurrently.

Request
 ├── fetch user
 ├── fetch recommendations
 ├── fetch inventory
 └── fetch pricing

If independent, these tasks can execute concurrently.

Data parallelism
→ same operation, different data

Task parallelism
→ different operations

10. Parallel Reduction

Suppose we need:

a + b + c + d + e + f + g + h

A sequential reduction is a chain:

((((a + b) + c) + d) + ...)

If the operation is associative, we can use a tree:

        +
      /        +     +
    / \   / \
   +   + +   +
  a b c d e f g h

The sequential dependency depth is approximately:

O(n)

while a balanced parallel reduction can have depth:

O(log n)

with sufficient parallel resources.

The uploaded material explicitly connects XOR’s associativity and commutativity to parallel reduction, MapReduce, GPU kernels, and distributed aggregation.


11. Associativity Enables Parallel Reduction

An operation is associative when:

(a ⊕ b) ⊕ c
=
a ⊕ (b ⊕ c)

Examples include:

addition
multiplication
minimum
maximum
XOR

This allows regrouping:

(a + b) + (c + d)

instead of:

((a + b) + c) + d

That is the mathematical foundation for many parallel reduction algorithms.


12. Floating-Point Caveat

Mathematical associativity does not always imply identical machine-level results.

Floating-point addition can produce different rounding behavior depending on grouping.

Therefore:

parallel floating-point reduction

may not be bit-for-bit identical to:

sequential reduction

This is a valuable Staff-level observation.


13. MapReduce

A classic large-scale pattern is:

Map

Shuffle / Partition

Reduce

For example, word counting:

Documents

Map

(word, 1)

Group by word

Reduce

(word, count)

The key idea is:

Partition the work
+
process independently
+
combine results

14. Synchronization

Parallel workers often need to coordinate.

Common mechanisms include:

locks
semaphores
barriers
atomic operations
condition variables
message passing

The challenge is that synchronization introduces dependencies.

Too much synchronization can eliminate the benefit of parallelism.


15. Race Conditions

A race condition occurs when the result depends on timing.

Suppose:

counter += 1

Two workers execute it simultaneously.

Conceptually:

counter = 10

Worker A reads 10
Worker B reads 10

A writes 11
B writes 11

Expected:

12

Actual:

11

The update was lost.


16. Critical Sections

A critical section is code accessing shared mutable state that requires coordination.

A strong Staff-level question is:

Can I eliminate the shared state instead of protecting it?

Often the best synchronization strategy is:

Don't share mutable state.

17. Prefer Local State

Instead of:

Many workers

shared counter

lock

use:

Worker 1 → local count
Worker 2 → local count
Worker 3 → local count
Worker 4 → local count

      reduce

This changes frequent synchronization into:

parallel computation
+
one reduction

18. Load Balancing

Suppose:

Worker 1 → 100 units
Worker 2 → 100 units
Worker 3 → 100 units
Worker 4 → 500 units

Workers 1–3 finish early.

The system still waits for Worker 4.

Therefore:

parallel execution time
≈ slowest worker

Load balancing is critical.


19. Static vs Dynamic Scheduling

Static

Partition work before execution:

Worker 1 → A
Worker 2 → B
Worker 3 → C
Worker 4 → D

Advantages:

simple
low scheduling overhead
predictable

Disadvantage:

possible load imbalance

Dynamic

Workers obtain tasks as they finish:

Task Queue

Worker 1
Worker 2
Worker 3
Worker 4

Advantage:

better load balancing

Disadvantage:

more scheduling overhead

20. Granularity

Parallel tasks can be very small or very large.

If tasks are too small:

useful work

scheduling overhead

synchronization

If tasks are too large:

less scheduling overhead
but
poor load balancing

Therefore we seek an appropriate task granularity.


21. Communication Overhead

In distributed systems, workers may need to communicate:

Worker A

network

Worker B

Network communication can dominate computation.

A good distributed algorithm often tries to:

move computation to data

rather than:

move large amounts of data to computation

22. Parallelism vs Concurrency

These terms are related but not identical.

Concurrency

Multiple tasks are in progress during overlapping periods.

Parallelism

Multiple tasks actually execute simultaneously on different processing resources.

Concurrency
→ dealing with many things

Parallelism
→ doing many things simultaneously

23. Python Perspective

For Python interviews, distinguish:

CPU-bound work

from:

I/O-bound work

CPU-bound work spends most of its time computing.

I/O-bound work spends significant time waiting for:

network
disk
database
external services

The appropriate concurrency strategy can differ.


24. Processes vs Threads

A useful high-level distinction is:

Threads
→ shared process memory

Processes
→ separate process memory

Threads can make shared-state coordination more complicated.

Processes provide stronger isolation but introduce:

process creation
serialization
inter-process communication
memory overhead

The right choice depends on workload and runtime behavior.


25. GIL Awareness

For CPython, the Global Interpreter Lock is an important interview consideration.

Do not simply say:

“Python cannot do parallelism.”

That is too broad.

Instead explain:

runtime semantics
+
workload type
+
execution model
=
appropriate strategy

At Staff level, nuance matters more than slogans.


26. Barrier Synchronization

Sometimes workers must complete one phase before the next begins.

Phase 1
──────────────
Worker A ✓
Worker B ✓
Worker C ✓
Worker D ✓

     Barrier

Phase 2

A barrier provides this coordination.

But barriers can become expensive when one worker is consistently slower.


27. Deadlocks

Deadlock occurs when workers wait indefinitely for one another.

Thread A holds Lock 1

waits for Lock 2

Thread B holds Lock 2

waits for Lock 1

Result:

A waits for B
B waits for A

Common prevention strategies include:

consistent lock ordering
short critical sections
timeouts
avoiding unnecessary locks
reducing shared mutable state

28. Sequential → Parallel Transformation

A powerful interview pattern is:

Sequential algorithm

Identify independent work

Partition

Local computation

Combine

Parallel algorithm

For example:

Sequential:
sum all values

Parallel:
partition values

local sums

reduce local sums

The XOR example in the available material illustrates this same transformation.


29. Parallelism and Machine Learning

The same principles appear throughout ML systems.

Dataset

Partition

Workers

Model computation

Gradient aggregation

Parameter update

Similarly:

LLM inference

request batching

parallel execution

scheduling / aggregation

The available material explicitly connects parallel reduction with GPU kernels and distributed aggregation.


30. Speedup vs Efficiency

Suppose:

1 processor → 100 seconds
4 processors → 30 seconds

Speedup:

100 / 30 ≈ 3.33

Ideal speedup:

Parallel efficiency:

3.33 / 4 ≈ 83%

This distinguishes:

more processors

from:

useful processors

31. Strong Scaling vs Weak Scaling

Strong scaling

Keep workload fixed:

same work
+
more processors

lower runtime

Weak scaling

Increase workload with processor count:

more processors
+
proportionally more work

roughly constant runtime

These answer different scalability questions.


32. Staff-Level Trade-offs

Dimension Question
Latency Does parallelism reduce critical-path time?
Throughput Can we process more work per second?
CPU How much additional compute is required?
Memory Do workers duplicate data?
Network How much data must move?
Synchronization How much coordination is required?
Reliability What happens when a worker fails?
Cost Is the speedup worth the infrastructure?
Complexity Does parallelism make the system harder to operate?

33. The Biggest Mistake

A common mistake is:

Problem is slow

Add more workers

Instead ask:

Why is it slow?

CPU?
I/O?
Lock contention?
Memory bandwidth?
Network?
Algorithmic complexity?
Load imbalance?
Serialization?

Only then decide whether parallelism is the right solution.


34. Staff/Principal Mental Model

Think in layers:

Layer 1 — Algorithm
What computation is required?

Layer 2 — Dependency
Which operations can run independently?

Layer 3 — Execution
How should work be scheduled?

Layer 4 — Hardware
CPU? GPU? Memory? Cache?

Layer 5 — Distributed System
How much communication is required?

Layer 6 — Production
Cost? Reliability? Observability?

The ability to move between these layers is a strong Staff-level signal.


35. Interview Checklist

Before finalizing a parallel solution:

□ What work can execute independently?

□ What dependencies exist?

□ What is the critical path?

□ What is the total amount of work?

□ Is the operation associative?

□ Can I use parallel reduction?

□ How will work be partitioned?

□ Is load balanced?

□ What synchronization is required?

□ Can shared mutable state be eliminated?

□ What communication is required?

□ What happens when a worker fails?

□ What is the expected speedup?

□ What is the parallel efficiency?

□ What limits scalability?

□ What is the cost?

36. Part 18 → Part 19

The progression now becomes:

Part 15 — Recursion

Decompose problems

Part 16 — Dynamic Programming

Reuse overlapping subproblems

Part 17 — Greedy Algorithms

Make provably safe local choices

Part 18 — Graphs

Model relationships and dependencies

Part 19 — Parallel Computing

Exploit independent work
while controlling dependencies
and coordination

37. Final Takeaway

Parallel computing is not simply:

more CPUs

It is fundamentally about:

Independent work

Partitioning

Parallel execution

Synchronization

Aggregation

Scalability

The most important Staff-level insight is:

The fastest parallel algorithm is often the one that minimizes coordination, not the one that uses the most workers.

The core mental model is:

Total Work
    +
Dependencies
    +
Communication
    +
Synchronization
    +
Hardware
    =
Actual Performance

Source Note

The available uploaded interview-preparation material does not expose a complete original Part/Chapter 19 text or numbered problem set. It does contain explicit Staff-level material on associativity, XOR reduction, parallel reduction, MapReduce, GPU kernels, and distributed aggregation. Therefore, this Part 19 article follows the same Staff/Principal preparation style while clearly distinguishing the expanded parallel-computing explanations from the limited source-specific material.