我尝试在我的OpenCl代码中添加#pragma unroll
和#pragma unroll <loop count>
但我没有看到延迟有任何改善。循环内的语句是独立的,应该并行运行。所以,我想知道OpenCL是否隐式展开循环,并且添加unroll pragma将无济于事。
我的部分代码就像这样
for(j = 0; j < 4; j++)
{
m[0][j] = p0[j] + p0[j+4];
m[0][j+4] = p0[j] - p0[j+4];
m[1][j] = p1[j] + p1[j+4];
m[1][j+4] = p1[j] - p1[j+4];
m[2][j] = p2[j] + p2[j+4];
m[2][j+4] = p2[j] - p2[j+4];
m[3][j] = p3[j] + p3[j+4];
m[3][j+4] = p3[j] - p3[j+4];
}
我正在使用OpenCL 2.0。
手动展开后的代码就像这样
m[0][0] = p0[0] + p0[0+4];
m[0][0+4] = p0[0] - p0[0+4];
m[1][0] = p1[0] + p1[0+4];
m[1][0+4] = p1[0] - p1[0+4];
m[2][0] = p2[0] + p2[0+4];
m[2][0+4] = p2[0] - p2[0+4];
m[3][0] = p3[0] + p3[0+4];
m[3][0+4] = p3[0] - p3[0+4];
m[0][1] = p0[1] + p0[1+4];
m[0][1+4] = p0[1] - p0[1+4];
m[1][1] = p1[1] + p1[1+4];
m[1][1+4] = p1[1] - p1[1+4];
m[2][1] = p2[1] + p2[1+4];
m[2][1+4] = p2[1] - p2[1+4];
m[3][1] = p3[1] + p3[1+4];
m[3][1+4] = p3[1] - p3[1+4];
m[0][2] = p0[2] + p0[2+4];
m[0][2+4] = p0[2] - p0[2+4];
m[1][2] = p1[2] + p1[2+4];
m[1][2+4] = p1[2] - p1[2+4];
m[2][2] = p2[2] + p2[2+4];
m[2][2+4] = p2[2] - p2[2+4];
m[3][2] = p3[2] + p3[2+4];
m[3][2+4] = p3[2] - p3[2+4];
m[0][3] = p0[3] + p0[3+4];
m[0][3+4] = p0[3] - p0[3+4];
m[1][3] = p1[3] + p1[3+4];
m[1][3+4] = p1[3] - p1[3+4];
m[2][3] = p2[3] + p2[3+4];
m[2][3+4] = p2[3] - p2[3+4];
m[3][3] = p3[3] + p3[3+4];
m[3][3+4] = p3[3] - p3[3+4];
答案 0 :(得分:1)
可能编译器正在展开,但没有重新排序指令以获得最佳性能。
可能不是关于指令级并行性还是填充流水线。
可能是内存访问模式。
如果编译器无法执行或重新排序指令,请举例如下:
m[0][0] = p0[0] + p0[0+4]; <---- contiguous addr = x
m[0][0+4] = p0[0] - p0[0+4];
m[1][0] = p1[0] + p1[0+4];
m[1][0+4] = p1[0] - p1[0+4];
m[2][0] = p2[0] + p2[0+4];
m[2][0+4] = p2[0] - p2[0+4];
m[3][0] = p3[0] + p3[0+4];
m[3][0+4] = p3[0] - p3[0+4];
m[0][1] = p0[1] + p0[1+4]; <---- contiguous addr = x+1
m[0][1+4] = p0[1] - p0[1+4];
m[1][1] = p1[1] + p1[1+4];
m[1][1+4] = p1[1] - p1[1+4];
m[2][1] = p2[1] + p2[1+4];
m[2][1+4] = p2[1] - p2[1+4];
m[3][1] = p3[1] + p3[1+4];
m[3][1+4] = p3[1] - p3[1+4];
m[0][2] = p0[2] + p0[2+4]; <---- contiguous addr = x+2
m[0][2+4] = p0[2] - p0[2+4];
m[1][2] = p1[2] + p1[2+4];
m[1][2+4] = p1[2] - p1[2+4];
m[2][2] = p2[2] + p2[2+4];
m[2][2+4] = p2[2] - p2[2+4];
m[3][2] = p3[2] + p3[2+4];
m[3][2+4] = p3[2] - p3[2+4];
m[0][3] = p0[3] + p0[3+4]; <---- contiguous addr = x+3
m[0][3+4] = p0[3] - p0[3+4];
m[1][3] = p1[3] + p1[3+4];
m[1][3+4] = p1[3] - p1[3+4];
m[2][3] = p2[3] + p2[3+4];
m[2][3+4] = p2[3] - p2[3+4];
m[3][3] = p3[3] + p3[3+4];
m[3][3+4] = p3[3] - p3[3+4];
所以如果由于这个原因失败了,你可以试试这个:
m[0][0] = p0[0] + p0[0+4];
m[0][1] = p0[1] + p0[1+4];
m[0][2] = p0[2] + p0[2+4];
m[0][3] = p0[3] + p0[3+4];
...
并对其余部分重新排序,因此对于所有数组,mem访问更好。但我不确定m数组,因为它可能是行主要或列主要,具体取决于设备。