OpenCL优化方法-消除访问内存数组引起的循环依赖关系

来源:互联网 发布:战国史se人物数据 编辑:程序博客网 时间:2024/06/08 10:25
消除访问内存数组引起的循环依赖关系
在单个工作项内核中包含ivdep pragma,可以声明对内存数组的访问不会导致循环依赖。在编译期间,OpenCL离线编译器的英特尔FPGA SDK创建了可确保加载和存储指令在依赖关系约束下运行的硬件。依赖约束的一个例子是依赖的加载和存储指令必须按顺序执行。ivdep pragma的存在指示离线编译器移除循环中加载和存储指令之间的额外硬件,此循环在内核代码中紧跟在pragma声明之后。额外硬件的删除可能会降低逻辑利用率,并降低单个工作项内核中的II值。
如果想要对循环内存数组的所有访问都不会导致循环依赖,可在内核代码中的循环之前添加#pragma ivdep行。
内核代码示例:
// no loop-carried dependencies for A and B array accesses
#pragma ivdep
for(int i = 0; i < N; i++) {
A[i] = A[i - X[i]];
B[i] = B[i - Y[i]];
要指定对循环内的特定内存数组的访问不会导致循环依赖,请在内核代码中的循环之前添加行#pragma ivdep数组(array_name)。
由ivdep pragma指定的数组必须是本地或专用的存储器数组,或指向全局,本地或专用存储器的指针变量。如果指定的数组是一个指针,则ivdep pragma也适用于可能与指定指针进行别名的所有数组。
由ivdep pragma指定的数组也可以是一个数组或一个struct的指针成员。
内核代码示例:
// No loop-carried dependencies for A array accesses
// The offline compiler will insert hardware that reinforces dependency
constraints for B
#pragma ivdep array(A)
for(int i = 0; i < N; i++) {
A[i] = A[i - X[i]];
B[i] = B[i - Y[i]];
}
// No loop-carried dependencies for array A inside struct
#pragma ivdep array(S.A)
for(int i = 0; i < N; i++) {
S.A[i] = S.A[i - X[i]];
}
// No loop-carried dependencies for array A inside the struct pointed by S
#pragma ivdep array(S->X[2][3].A)
for(int i = 0; i < N; i++) {
S->X[2][3].A[i] = S.A[i - X[i]];
}
// No loop-carried dependencies for A and B because ptr aliases
// with both arrays
int *ptr = select ? A : B;
#pragma ivdep array(ptr)
for(int i = 0; i < N; i++) {
A[i] = A[i - X[i]];
B[i] = B[i - Y[i]];
}
// No loop-carried dependencies for A because ptr only aliases with A
int *ptr = &A[10];
#pragma ivdep array(ptr)
for(int i = 0; i < N; i++) {
A[i] = A[i - X[i]];
B[i] = B[i - Y[i]];
}