Oracle® Solaris Studio 12.4: C User's Guide

Exit Print View

Updated: March 2015
 
 

3.2.1  Data Dependence and Interference

The C compiler performs analysis on loops in programs to determine whether executing different iterations of the loops in parallel is safe. The purpose of this analysis is to determine whether any two iterations of the loop could interfere with each other. Typically, this problem occurs if one iteration of a loop could read a variable while another iteration is writing the very same variable. Consider the following program fragment:

Example 3-1  Loop With Dependence
for (i=1; i < 1000; i++) {
    sum = sum + a[i]; /* S1 */
}

In this example, any two successive iterations, i and i+1, will write and read the same variable sum. Therefore, in order for these two iterations to execute in parallel some form of locking on the variable would be required. Otherwise, allowing the two iterations to execute in parallel is not safe.

However, the use of locks imposes overhead that might slow down the program. The C compiler will not ordinarily parallelize the loop in the example above because there is a data dependence between two iterations of the loop. Consider another example:

Example 3-2  Loop Without Dependence
for (i=1; i < 1000; i++) {
    a[i] = 2 * a[i]; /* S1 */
}

In this case, each iteration of the loop references a different array element. Therefore different iterations of the loop can be executed in any order. They may be executed in parallel without any locks because no two data elements of different iterations can possibly interfere.

The analysis performed by the compiler to determine whether two different iterations of a loop could reference the same variable is called data dependence analysis. Data dependences prevent loop parallelization if one of the references writes to the variable. The dependence analysis performed by the compiler can have three outcomes:

  • There is a dependence, in which case, executing the loop in parallel is not safe.

  • There is no dependence, in which case the loop may safely execute in parallel using an arbitrary number of processors.

  • The dependence cannot be determined. The compiler assumes, for safety, that a dependence might prevent parallel execution of the loop and will not parallelize the loop.

In the following example, whether two iterations of the loop write to the same element of array a depends on whether array b contains duplicate elements. Unless the compiler can determine this fact, it must assume there might be a dependence and not parallelize the loop.

Example 3-3  Loop That Might Contain Dependencies
for (i=1; i < 1000; i++) {
    a[b[i]] = 2 * a[i];
}