Kahibaro
Discord Login Register

6.2 Types of parallelism

Overview

Parallel programs can exploit different kinds of “sameness” or “independence” in a problem. When we talk about types of parallelism, we are usually classifying what is being done in parallel:

This chapter focuses on recognizing and structuring these types of parallelism, not on the specific programming models (which are covered later with OpenMP, MPI, GPUs, etc.).

Dimensions of Parallelism

Before focusing on the two main types (task and data), it helps to see that parallelism can be classified along several axes:

The rest of this chapter focuses on the “what” dimension: task vs data parallelism, and how to recognize and use them.

Task Parallelism (Functional Parallelism)

Task parallelism appears when you can identify distinct units of work that can proceed (partly or fully) independently, possibly on different data.

Characteristics

Typical features:

Conceptually, you are parallelizing over operations or activities, not primarily over individual data elements.

Examples of Task Parallelism

Each scenario is a separate task: same code, different inputs. They can run in parallel with almost no communication.

When handling many datasets, you can pipeline:

Different stages for different datasets run in parallel (a pipeline of tasks).

as separate tasks that periodically exchange boundary conditions and loads.

When Task Parallelism Works Well

Task parallelism is effective when:

Many “embarrassingly parallel” problems are naturally expressed as collections of independent tasks.

Challenges

In practice, you often need to design tasks to be similar in cost, or use dynamic scheduling mechanisms to distribute them efficiently.

Data Parallelism

Data parallelism appears when the same operation is applied to many data items that are largely independent.

Characteristics

Typical features:

Conceptually, you are parallelizing over data elements, not over distinct functions.

Examples of Data Parallelism

Each element update can be done independently (or nearly so) in parallel.

Each sample evaluation is a data element processed in parallel.

Data Decomposition

To exploit data parallelism, you typically decompose the data:

Each processing element (thread, process, GPU block, etc.) handles one or more chunks.

The choice of decomposition affects:

Operations That Fit Data Parallelism

The following patterns naturally map to data parallelism:

Parallel implementations of these patterns are the basis of many HPC kernels and also appear in GPU programming and vectorization.

Comparing Task and Data Parallelism

Although often presented as distinct, in real applications you almost always see both types.

Conceptual Difference

Common Misconceptions

Examples of Mixed Use

Most real HPC applications mix task and data parallelism:

Being able to identify both levels helps you design scalable codes and workflows.

Matching Problem Structure to Parallelism Type

Choosing an appropriate type (or mix) of parallelism is mostly about recognizing structure in your problem.

When to Prefer Task Parallelism

Consider a task-centric approach if:

In such cases, you typically want to maximize throughput by executing as many independent tasks as resources allow.

When to Prefer Data Parallelism

Consider a data-centric approach if:

In such cases, you structure computations around data decomposition and parallel kernels.

Hybrid and Hierarchical Parallelism

Modern HPC systems are hierarchically parallel (nodes, cores, vector units, GPUs), and many applications are hierarchically structured as well. This naturally leads to combinations of parallelism types.

Nested Parallelism

You can layer types of parallelism:

This can be extended to multiple nested levels, each matching a hardware or algorithmic level.

Spatial vs Functional Decomposition

Two common ways of combining parallelism:

Many large codes use a mix of both: subdomains (data parallel) solved by different solvers or physics modules (tasks), which themselves may be data-parallel internally.

Practical Guidelines

When examining a problem to identify parallelism:

  1. List independent activities (tasks)
    • Are there many parameter sets, time windows, or input files that can be handled separately?
    • Are there distinct stages that can overlap in time?
  2. Inspect your data structures
    • Do you operate on large arrays, grids, or collections where operations are similar across elements?
    • Can you partition these data structures cleanly?
  3. Identify dependencies
    • Where do results from one part of the work feed into another?
    • Are those dependencies between tasks, or just along boundaries of data partitions?
  4. Match to hardware
    • Use data parallelism where vector units or GPUs can help.
    • Use task parallelism to exploit many cores on independent or loosely coupled work.
  5. Expect to mix types
    • Rarely is a real application purely task- or data-parallel.
    • Plan for a hierarchical design where both types co-exist.

Understanding these types of parallelism at the conceptual level will make it easier to grasp the concrete programming models and performance topics discussed in later chapters.

Views: 47

Comments

Please login to add a comment.

Don't have an account? Register now!