OpenMP
**OpenMP Task Parallelism** is **a fine-grained parallel execution model allowing dynamic creation and scheduling of independent units of work across threads, enabling irregular and recursive computations** — superior to loop-based parallelism for unstructured algorithms. Task parallelism provides flexibility for problems not expressible as simple loops. **Task Creation and Semantics** use #pragma omp task directive creating deferred work units, with task_shared and task_private clauses controlling variable scope. Task creation is lightweight—OpenMP runtime maintains task queues and schedules execution across threads. Task groups (taskgroup) provide synchronization boundaries where all descendant tasks must complete before continuing. **Scheduling Strategies and Load Balancing** employ dynamic scheduling where the runtime assigns ready tasks to idle threads, naturally balancing load across heterogeneous workloads. Work-stealing algorithms in modern OpenMP allow threads to steal tasks from others' queues when idle, improving utilization. Schedule kinds include static (predetermined allocation), dynamic (runtime allocation with chunk size), guided (decreasing chunk sizes), and auto (compiler/runtime decides). **Task Dependencies and Synchronization** via depend clauses (depend(in:var), depend(out:var), depend(inout:var)) create data-flow graphs where upstream tasks producing data trigger downstream consumers. The runtime resolves dependencies and schedules appropriately, enabling sophisticated parallelization of sparse matrix operations, computational kernels with producer-consumer patterns, and recursive algorithms. **Applications in Recursive Algorithms** make tasks ideal for tree processing (tree traversal, binary search, divide-and-conquer), graph algorithms (recursive DFS, quicksort), and adaptive mesh refinement where task granularity varies. Fibonacci computation naturally expresses as recursive tasks—each level spawns independent tasks, runtime handles load balancing better than manual thread management. **Nested Task Parallelism** allows tasks to create additional tasks, supporting multiple parallelism levels simultaneously. **Task parallelism with dependency resolution enables efficient expression of irregular, data-dependent computations** that would require complex synchronization with traditional loop-based parallelism.