What is Data Dependency?

A position in which an instruction is dependent on a result from a sequentially earlier instruction before it can be done its execution. In high-performance processors operating pipeline or superscalar techniques, a data dependency will learn an interruption in the flowing services of a processor pipeline or prevent the parallel issue of instructions in a superscalar processor.

Consider two instructions ik and ii of the same program, where ik precedes ii. If ik and ii have a common register or memory operand, they are data-dependent on each other, except when the common operand is used in both instructions as a source operand.

An example is when ii uses the result of ik as a source operand. In sequential execution data, dependencies do not generate any issue, because instructions are implemented rigidly in the stated sequence.

Data dependency can appear either in ‘straight-line code’ between subsequent instructions or in a loop between instructions belonging to subsequent iterations of a loop as shown in the figure.

Therefore, by ‘straight-line code’ it can define any code sequence, even instructions of a loop body that does not involve instructions from subsequent loop iterations. Straight-line code can include three different types of dependencies, known as RAW (Read after Write), WAR (Write after Read), and WAW (Write after Write) dependencies.

Data dependencies in straight-line code

Data dependencies for memory data can be interpreted in a similar method.

RAW dependencies − Consider two assembly language instructions −

i1: load r1, a;
i2: add  r2, r1, r1;

Therefore, instruction i2 uses r1 as a source. As a result, i2 cannot be directly implemented just before r1 has been loaded by i1. Thus, i2 is RAW-dependent on it. RAW dependencies are also known as flow dependencies. They are true dependencies because they cannot be abandoned.

RAW dependencies can be divided into load-use and define-use dependencies. In the following example, the requested source operand has to be loaded first. This method can handle a load-use dependency. By compare, if the requested source operand is represented in the previous instruction, in the instruction sequence.

i1: mul r1, r4, r5;
i2: add r2, r1, r1;

This type of RAW dependency is labeled as a define-use dependency.

WAR dependencies − Consider the execution of the following instructions −

i1: mul r1, r2, r3;
i2: add r2, r4, r5;

In this case, i2 writes r2 while i1 uses r2 as a source. If for any reason, i2 were to be implemented ahead of i1 then the initial content of r2 would be rewritten previously than it is read by instruction r1, which can lead to an incorrect result.

WAW dependencies: Two instructions are WAW-dependent (or output dependent) if they both write the similar destination, as in the following example −

i1: mul r1, r2, r3;
i2: add r1, r4, r5;

This type of dependency is also a false dependency and can be removed in a similar method as WAR dependencies through register renaming. A WAW dependency determination when the execution of the contained logically preceding instruction will be done and the produced result can refresh the program state.