01 - Multiprocessing
Section 1.1: HPC landscape overview
High-Performance Computing (HPC) includes various strategies to accelerate computation by leveraging hardware parallelism. Choosing the right approach depends on the nature of the problem, the scale of data, and available infrastructure.
Section 1.2: Introduction to the multiprocessing module
The multiprocessing module allows you to run code in
parallel using multiple processor cores, enabling faster execution of
computationally intensive tasks. It achieves this by creating and
managing separate processes, each with its own memory space.
Section 1.3: Using Process, Queue, Pipe, and Pool
These modules provide tools for concurrent execution, allowing you to distribute workloads across multiple cores or machines. They enable parallel processing and communication between processes.
Section 1.4: Introduction to concurrent.futures for cleaner parallel execution
concurrent.futures provides a high-level interface for asynchronously executing callables, simplifying parallel and concurrent programming in Python. It abstracts away much of the complexity of managing threads or processes.
Section 1.5: Examples of CPU-bound tasks with performance profiling
CPU-bound tasks are limited primarily by the processing power of the CPU. Performance profiling helps identify such tasks and pinpoint bottlenecks.
Section 1.6: Comparison with sequential execution
Sequential execution processes instructions one after another, which can be straightforward but is often inefficient for complex tasks. Parallel execution offers a potential speedup by dividing work across multiple processing units.
Section 1.7: Synchronization and locking considerations
Ensuring that multiple processes or threads access shared resources in a controlled manner is crucial to prevent data corruption and unexpected behavior. Synchronization mechanisms and locking are fundamental tools for achieving this.
Section 1.8: Profiling CPU-bound vs I/O-bound tasks
Understanding whether a task is primarily limited by CPU processing or data input/output is crucial for optimizing performance. This distinction dictates the most effective optimization strategies.
Exercise: Parallel prime number calculation
Objective: Implement a simple parallel prime number calculation using Python's multiprocessing module.
Instructions:
- You are given a script primes.py that takes an integer n as input and calculates all prime numbers up to n.
- Modify the script to use the multiprocessing module to divide the range of numbers (2 to n) into chunks and have each process calculate the prime numbers within its chunk.
- Combine the results from all processes to produce the final list of prime numbers.
Expected Learning Outcome: You will understand how to use multiprocessing to parallelize a simple task and combine the results from multiple processes.
Exercise: Signal filtering comparison (sequential vs parallel)
Objective: To understand the performance difference between sequential and parallel signal filtering using Python's multiprocessing module.
Instructions:
- You are given a script signal_filter.py that simulates a simple signal filtering process. This script takes a list of numbers (representing a signal) and applies a simple moving average filter.
- Modify the script to perform the filtering both sequentially and using multiprocessing. The signal should be divided into chunks for parallel processing.
- Compare the execution time of the sequential and parallel versions for a signal of length 10,000. You can use the time module for timing.
Expected Learning Outcome: You should be able to compare the performance of sequential and parallel processing for a simple task and understand the basic principles of parallelization.