OpenCL中的“循环展开”是隐式还是显式?

时间:2017-01-27 11:50:02

标签: opencl

我尝试在我的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];

1 个答案:

答案 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数组,因为它可能是行主要或列主要,具体取决于设备。