Visible to Intel only — GUID: clp1468865630147
Ixiasoft
Visible to Intel only — GUID: clp1468865630147
Ixiasoft
6.2. Loop-Carried Dependencies (ivdep Pragma)
The ivdep pragma tells the compiler that a memory dependency between loop iterations can be ignored. Ignoring the dependency saves area and lowers the loop initiation interval (II) of the affected loop because the hardware required for avoiding data hazards is no longer required.
You can provide more information about loop dependencies by adding the safelen(N) clause to the ivdep pragma. The safelen(N) clause specifies the maximum number of consecutive loop iterations without loop-carried memory dependencies. For example, #pragma ivdep safelen(32) indicates to the compiler that there are a maximum of 32 iterations of the loop before loop-carried dependencies might be introduced. That is, while #pragma ivdep promises that there are no implicit memory dependency between any iteration of this loop, #pragma safelen(32) promises that the iteration that is 32 iterations away is the closest iteration that could depend on this iteration.
- a component memory array
- a pointer argument
- a pointer variable that points to a component memory
- a reference to an mm_host object
Use Case 1:
If all accesses to memory arrays inside a loop do not cause loop-carried dependencies, add #pragma ivdep before the loop.
1 // no loop-carried dependencies for A and B array accesses
2 #pragma ivdep
3 for(int i = 0; i < N; i++) {
4 A[i] = A[i + N];
5 B[i] = B[i + N];
6 }
Use Case 2:
You may specify #pragma ivdep array (array_name) on particular memory arrays instead of all array accesses. This pragma is applicable to arrays, pointers, or pointer members of structs. If the specified array is a pointer, the ivdep pragma applies to all arrays that may alias with the specified pointer.
1 // No loop-carried dependencies for A array accesses
2 // Compiler inserts hardware that reinforces dependency constraints for B
3 #pragma ivdep array(A)
4 for(int i = 0; i < N; i++) {
5 A[i] = A[i - X[i]];
6 B[i] = B[i - Y[i]];
7 }
8
9 // No loop-carried dependencies for array A inside struct
10 #pragma ivdep array(S.A)
11 for(int i = 0; i < N; i++) {
12 S.A[i] = S.A[i - X[i]];
13 }
14
15 // No loop-carried dependencies for array A inside the struct pointed by S
16 #pragma ivdep array(S->X[2][3].A)
17 for(int i = 0; i < N; i++) {
18 S->X[2][3].A[i] = S.A[i - X[i]];
19 }
20
21 // No loop-carried dependencies for A and B because ptr aliases
22 // with both arrays
23 int *ptr = select ? A : B;
24 #pragma ivdep array(ptr)
25 for(int i = 0; i < N; i++) {
26 A[i] = A[i - X[i]];
27 B[i] = B[i - Y[i]];
28 }
29
30 // No loop-carried dependencies for A because ptr only aliases with A
31 int *ptr = &A[10];
32 #pragma ivdep array(ptr)
33 for(int i = 0; i < N; i++) {
34 A[i] = A[i - X[i]];
35 B[i] = B[i - Y[i]];
36 }
<quartus_installdir>/hls/examples/tutorials/best_practices/loop_memory_dependency