GPU Parallelism in Graphics Workloads

Scope

This document explains how modern GPUs extract parallelism from graphics workloads across major vendors, with focus on:

  1. How triangles using different shaders execute concurrently
  2. How pixels from the same triangle execute together despite variable latency
  3. How outputs from many parallel shader invocations are composited in correct visual order

The exact microarchitecture differs by vendor and generation, but the execution model is broadly similar.


1. Parallelism Layers in the Graphics Pipeline

GPU parallelism is extracted at several levels simultaneously:

  1. Command level:

    • Multiple command buffers or queues can be in flight.
    • Graphics and compute may overlap if resources permit.
  2. Draw/dispatch level:

    • Different draw calls can overlap in front-end work.
    • Pixel-heavy draws and vertex-heavy draws can overlap in different pipeline stages.
  3. Primitive level:

    • Many triangles are transformed, culled, binned, and rasterized concurrently.
  4. Fragment/pixel level:

    • Fragments are grouped into SIMD/SIMT execution quanta (warps/waves/subgroups).
    • Many groups run in parallel across many cores.
  5. Instruction level:

    • Within each core, schedulers interleave independent instruction streams and switch to ready groups to hide latency.

A key concept: GPUs rely heavily on throughput and latency hiding, not single-thread low latency.


2. How Triangles with Different Shaders Run in Parallel

Practical reality

Within one draw call, all primitives normally use one pipeline state object (PSO), meaning one selected vertex/fragment shader pair (plus variants). So a single draw does not usually mix unrelated shaders per triangle.

Different shader programs typically appear across different draws, material batches, render passes, or pipeline state changes.

How parallel overlap still occurs

Even when shader programs differ, overlap occurs because:

  1. Front-end and back-end decoupling:

    • While one draw is in raster/fragment stages, another may be in vertex or setup stages.
  2. Deep hardware queues:

    • Work from multiple draws can coexist in internal queues (subject to hazards and resource limits).
  3. Multi-engine scheduling:

    • Async compute can run alongside graphics where architecture and dependencies allow.
  4. Fine-grained core scheduling:

    • Cores can host many resident groups from different kernels/shader programs (implementation-dependent), switching among ready groups.

Constraints:


3. Pixel/Fragment Parallelism Inside a Triangle

After rasterization, covered samples/fragments are generated and grouped into execution quanta:

Why fragments from one triangle run "together"

Fragments are usually issued in spatially coherent tiles/quads/subgroups. This improves:

  1. Texture cache locality
  2. Derivative computations for mip selection
  3. Control-flow coherence

Variable-latency operations (texture fetch, memory access)

Texture fetch latency can vary due to cache hit/miss, compression state, format conversion, and memory contention. GPUs handle this by:

  1. Massive multithreading:

    • Keep many warps/waves resident per core.
  2. Hardware scheduling:

    • If one wave stalls on texture/memory, scheduler issues another ready wave.
  3. Scoreboarding/dependency tracking:

    • Instructions execute when operands are ready.
  4. Prefetch and caches:

    • Texture units and caches reduce average latency.
  5. Occupancy tuning:

    • More resident waves improve hiding of long-latency operations, until register/shared-memory pressure limits occupancy.

Net effect: not every fragment finishes at the same time, but throughput remains high.

A 4-stage quad executor model

The idea of running one quad through a 4-stage, strictly in-order executor is plausible as a simulator or small-GPU design point.

One way to think about it is:

  1. Treat the four fragments in a 2x2 quad as four logical lanes.
  2. Advance one quad lane per cycle, or one stage per cycle, while keeping the other lanes' state resident.
  3. Use SMT-like time slicing so the pipeline stays busy even though execution is strictly ordered within each lane.

That gives you a machine that is not out-of-order, but still has enough lane-level concurrency to model quad execution, derivatives, and masked control flow.

Why this is a good mental model

What it means for register pressure

This model increases pressure on the architectural register file because each lane needs its own live state until the quad completes.

In practice this means:

What it means for in-pipe memories and accumulators

The "in-pipe" state for such a machine is usually not just one set of pipeline registers. You need small lane-local or quad-local memories for:

If the design is strictly in order, these buffers act like stage-local holding registers and scoreboards:

So the main trade-off is straightforward:

For a browser simulator or research GPU, this is a useful point on the design space because it is simple enough to implement, but still captures the real cost of varyings, per-lane state, and pipeline residency.


4. Divergence and Coherence

SIMD/SIMT groups execute best when lanes follow similar control flow.

Vendors optimize this differently (compiler heuristics, scheduling, cache layout), but the fundamental cost model is shared.


5. Vendor Architectures: How Parallelism Is Extracted

NVIDIA (GeForce/RTX/Data Center)

AMD (RDNA/CDNA lineage for graphics/compute emphasis)

Intel (Xe family)

Apple (AGX, tile-based deferred rendering style)

Mobile vendors (ARM Mali, Qualcomm Adreno, Imagination)

Important note: exact scheduling and cache details are often proprietary and vary per generation.


6. Correct Compositing and Draw Order Under Massive Parallelism

Parallel execution does not mean random final order. Correctness is enforced by pipeline rules and fixed-function tests.

Opaque geometry path (common case)

  1. Rasterization generates fragments.
  2. Per-fragment tests (scissor, stencil, depth) determine visibility.
  3. Passing fragments write color/depth.

Depth testing means only nearest visible surfaces survive (for standard less/greater depth modes), independent of internal execution timing.

Transparent/blended geometry path

With blending enabled, order often matters because blending is not generally commutative:

Thus, even though many shader invocations run in parallel, output merger/ROP logic applies operations in a manner consistent with graphics API ordering guarantees.

Early-Z / Late-Z

This affects performance, not final correctness.

Tile-based compositing nuance

In tile-based GPUs:

This reduces bandwidth while preserving API-visible output semantics.


7. How Different Shader Programs Are Composited Correctly

When different shaders contribute to the same frame:

  1. CPU/driver submits ordered command streams.
  2. Hardware may overlap execution internally.
  3. Synchronization points, render pass boundaries, and barriers enforce visibility/order constraints.
  4. Output merge stage plus depth/stencil/blend rules define final per-pixel result.

So internal scheduling is opportunistic, but externally visible results follow API ordering and attachment rules.


8. Typical Ordering Tools Used by APIs/Drivers

Across modern APIs (Metal, Vulkan, D3D12):

  1. Render pass boundaries
  2. Resource state transitions
  3. Memory barriers
  4. Subpass dependencies (where applicable)
  5. Queue synchronization primitives (fences/semaphores/events)

These constrain or permit overlap while preserving correctness.


9. Performance Implications for Shader Authors

To maximize parallel efficiency:

  1. Keep control flow coherent across neighboring pixels.
  2. Minimize random memory access and exploit texture locality.
  3. Balance register usage to maintain occupancy.
  4. Reduce unnecessary state changes and shader permutations.
  5. Separate opaque and transparent passes with intentional ordering.
  6. Use depth pre-pass or early depth strategies when beneficial.

10. Summary

Modern GPUs extract parallelism from graphics workloads by combining:

  1. Many in-flight draws/primitives/fragments
  2. SIMD/SIMT subgroup execution
  3. Fast hardware scheduling to hide texture/memory latency
  4. API- and pipeline-level ordering rules for correct final composition

Triangles and pixels do execute in massive parallel fashion, but final frame correctness is maintained by depth/stencil/blend/output-merge semantics and explicit synchronization constraints.


11. Appendix: Concrete Frame Example with Ordering and Barriers

This example shows a typical frame with opaque geometry, transparent geometry, and post-processing.

Example frame plan

  1. Depth pre-pass (optional)
  2. Opaque pass (G-buffer or forward)
  3. Lighting pass (if deferred)
  4. Transparent pass
  5. Post-process pass
  6. UI/composite pass

Step-by-step correctness model

Step 1: Depth pre-pass

Step 2: Opaque color/G-buffer pass

Barrier A (if deferred path)

Step 3: Lighting/full-screen pass

Step 4: Transparent pass

Barrier B

Step 5: Post-process

Step 6: UI/composite

What can overlap safely

  1. Vertex/front-end work for later draws can overlap while earlier draws are rasterizing.
  2. Async compute (for example culling, SSR prep, particles) may overlap graphics if resources are disjoint or synchronized correctly.
  3. Independent post-process branches can run concurrently if they read immutable inputs and write distinct outputs.

What must be ordered

  1. Any pass that reads a resource written by a prior pass must wait for visibility via barriers/dependencies.
  2. Transparent blending to the same target region must respect draw ordering policy.
  3. Final presentation must wait until all writes to the presentable image are complete.

Minimal mental model