Skip to content

Distributed Computing

Parallel computing harnesses multiple cores within a single machine. But a single machine has limits: a typical CPU has 4 to 128 cores, and the machine has a fixed amount of memory. What if your problem needs more?

Distributed computing breaks through these limits by spreading work across multiple machines connected by a network. Unity has over 6,000 CPU cores across hundreds of nodes. Distributed computing is how you tap into that collective power.

Part of a series

This page is a deep dive into one of three parallel programming paradigms. For the big picture and a framework for choosing between them, start with the Parallel Programming overview.

The Distributed Supermarket Checkout

Your supermarket is overwhelmed. Even with every checkout lane open, the lines stretch to the back of the store. The solution? Direct the overflow to other stores in the chain. Each store operates independently with its own cashiers and lanes, and you can keep adding stores as demand grows.

This is distributed computing: scaling out across multiple independent systems, each with its own resources. The throughput can grow almost without limit, but now you need logistics to coordinate between stores (which store handles which customers, how do you collect the total sales at the end of the day?).

The Distributed Where's Waldo?

Sixty-four people sit in 64 separate rooms, each with their own laptop. You mail each person a section of the image. Each person searches their section independently and sends back their result. If Waldo is in section 37, person 37 reports "Found him!" and you're done.

The search itself is fast: 64 people working simultaneously. But notice the overhead that didn't exist in the parallel version:

  • Distributing the data: You had to send each section to each room (network transfer)
  • Collecting results: You had to receive answers back from all 64 people
  • Coordination: Someone had to decide how to split the image and who gets which piece

That communication overhead is the fundamental cost of going distributed.

The Message-Passing Model

In distributed computing, each process runs on a potentially different machine and has its own private memory. There's no shared memory to read from. If Process A has data that Process B needs, Process A must explicitly send a message containing that data, and Process B must explicitly receive it.

This is the message-passing model, and it's the dominant paradigm for distributed HPC. The most widely used standard for message passing is MPI (Message Passing Interface).

A typical pattern looks like this:

sequenceDiagram
    participant R0 as Orchestrator<br/>(Rank 0)
    participant R1 as Worker<br/>(Rank 1)
    participant R2 as Worker<br/>(Rank 2)
    participant R3 as Worker<br/>(Rank 3)

    R0->>R0: Split work into chunks
    R0->>R1: Send chunk 1
    R0->>R2: Send chunk 2
    R0->>R3: Send chunk 3
    R0->>R0: Process chunk 0

    R1->>R1: Compute
    R2->>R2: Compute
    R3->>R3: Compute

    R1->>R0: Send results
    R2->>R0: Send results
    R3->>R0: Send results
    R0->>R0: Combine all results

One process (often called rank 0) acts as the orchestrator: it divides the work, distributes it to worker processes, and collects the results. Each worker process runs independently in its own memory space, potentially on a different physical machine.

Rank = process ID in MPI

In MPI terminology, each process is assigned a unique integer called its rank, starting at 0. If you launch 8 MPI processes, they are numbered rank 0 through 7. Rank 0 conventionally serves as the coordinator.

Communication Overhead

Communication is the price of distribution. Every message between processes costs time:

  • Network latency: Even on a high-speed cluster interconnect, sending a message takes time (microseconds to milliseconds depending on message size and network)
  • Serialization: Data must be packed into a format suitable for transmission and unpacked at the other end
  • Synchronization: If Process B can't continue until it receives data from Process A, it sits idle waiting. That's wasted compute time.

The practical impact: more processes means more communication, which means diminishing returns.

Task granularity matters

Consider splitting 128 tasks across different numbers of workers:

Workers Tasks per worker Communication overhead
2 64 each Minimal — just 2 send/receive pairs
8 16 each Moderate — 8 send/receive pairs
32 4 each High — 32 pairs, each for only 4 tasks
128 1 each Extreme — 128 pairs, communication may dominate

If each task is small, the time spent sending and receiving may exceed the time saved by distributing. This is the granularity tradeoff: tasks need to be large enough that the computation time dwarfs the communication time.

Amdahl's Law still applies here, but with a twist: the "serial fraction" now includes communication time. Every send, receive, and synchronization point adds to the portion of your program that can't be parallelized.

Choosing the right decomposition

How you split the work matters enormously. An uneven split means some workers finish early and sit idle while others are still computing. This load imbalance wastes the resources you're paying for.

Even Split — all workers finish together
Worker 0
Worker 1
Worker 2
Worker 3
Uneven Split — workers 1–3 idle while worker 0 finishes
Worker 0
Worker 1
Worker 2
Worker 3

In the uneven case, Workers 1–3 finish and idle while Worker 0 grinds through its oversized chunk. The total wall-clock time is determined by the slowest worker.

When to Use Distributed Computing

Distributed computing is the right tool when:

  • Your problem is too large for a single machine — either too many CPU cores needed or too much memory required
  • The workload scales well with more processors — adding workers yields meaningful speedup
  • You have access to a cluster like Unity
  • The expected speedup justifies the additional complexity of distributed programming

The scale advantage

The reason distributed computing dominates HPC is simple: it's the only paradigm that scales beyond a single machine. A single Unity node might have 20–40 cores. The cluster as a whole has thousands. If your problem benefits from 200 cores, you must distribute it across multiple nodes.

When not to distribute

Don't default to distributed computing just because you're on a cluster. If your workload fits on a single node, parallel computing is simpler, faster (no network overhead), and easier to debug. Only distribute when you have to.

Combining Paradigms

Real-world HPC applications often combine paradigms for maximum performance:

  • Distributed + Parallel: Use MPI to spread work across nodes, and within each node use multiple threads or processes to use all available cores. This is the classic hybrid MPI + OpenMP pattern.
  • Distributed + Concurrent: An orchestrator process might use async I/O to manage communication with many workers without blocking.

These hybrid approaches extract the most performance from cluster hardware, but they also combine the complexity of multiple paradigms. Start simple; go hybrid only when profiling shows you need it.

Limitations

Communication overhead. The more processes communicate, the more time is spent on messaging instead of computing. Fine-grained tasks that require frequent data exchange between processes may see little or no speedup, or even slowdowns.

Debugging difficulty. When something goes wrong in a distributed program, the bug might involve timing-dependent interactions between processes running on different machines. Reproducing and diagnosing such bugs is significantly harder than debugging sequential or even parallel code.

Load balancing. Uneven work distribution means some processes idle while others are overloaded. Achieving good load balance requires understanding your problem's structure and sometimes dynamic redistribution of work.

Amdahl's Law compounds. The serial fraction now includes not just inherently sequential code, but also all communication and synchronization. As you add more nodes, the relative cost of communication grows, eventually dominating the computation.

Infrastructure dependency. Your program's performance depends on the cluster's network interconnect, not just its CPUs. A slow or congested network can bottleneck an otherwise well-parallelized application.

What's Next

Ready to write distributed code? Start with these recipes:

  • MPI Hello World — Your first multi-process program on Unity
  • mpi4py — Distributed computing in Python with MPI

Or explore the other paradigms: