Balance. While identifying tasks that can run in parallel, programmers
must also ensure that the tasks perform equal work of equal value. In
some instances, a certain task may not contribute as much value to the
overall process as other tasks. Using a separate execution core to run that
task may not be worth the cost.
3. Data splitting. Just as applications are divided into separate tasks, the
data accessed and manipulated by the tasks must be divided to run on
separate cores.
4. Data dependency. The data accessed by the tasks must be examined for
dependencies between two or more tasks. When one task depends on
data from another, programmers must ensure that the execution of the
tasks is synchronized to accommodate the data dependency. We examine
such strategies in Chapter 5.
5. Testing and debugging. When a program is running in parallel on
multiple cores, many different execution paths are possible. Testing and
debugging such concurrent programs is inherently more difficult than
testing and debugging single-threaded applications.