Detect race conditions and use synchronization mechanisms to avoid them.
Estimate the problems that may result from erroneous use of synchronization mechanisms (e.g. deadlocks).
Assess data dependency situations, i.e. an instruction reading the data written by a preceding instruction in the source code, and anti dependencies, i.e. an instruction having to read data before a succeeding instruction overwrites it, and output dependencies, i.e. instructions writing to the same memory location.
Use data parallelism, e.g. applying parallel streams of identical instructions to different elements of appropriate data structures such as arrays.
Apply the concept of functional parallelism, i.e. executing a set of distinct functions possibly using the same data.
Assess the applicability of parallel language extensions like OpenMP.