Recipe for parallelizing a program. 1) Pick a concurrency strategy - How to break down the entire task into smaller units of work? - Data parallel, Task parallel, Hybrid - Will need to anticipate some of the coding you'll do next 2) Code up units of work - Write down the parameters of that work (e.g., what varies for the chunk done by thread 1 vs. thread 2 vs. thread 3 etc.) - Write down functions that do the work, given the parameters. - Test those functions in a single-threaded scenario, e.g., make a loop that calls your functions N times to compute the total result. 3) Identify and correct the concurrency hazards of executing the units of work in parallel - Look for concurrent accesses to shared datastructures. What could go wrong? - How to fix these hazards? - E.g., use synchronization, make copies, etc. - Also, enforce an ordering to avoid parallel access if needed 4) Choose a task execution policy - Choose how you will execute your tasks - E.g., thread pool, work-stealing scheduler, etc. - Choose the number of threads you will want - May need several queues and executors if there are dependencies between the tasks. - Do performance testing to see the effects of different concurrency strategies, sync mechanisms, etc. to find best performance.