0

我有一段这样的 OpenCL 代码

if (Sum[0] < Best)
{
    Best = Sum[0];
    iBest = 1;
    *aBits = Bits[0];
}

if (Sum[1] < Best)
{
    Best = Sum[1];
    iBest = 2;
    *aBits = Bits[1];
}

if (Sum[2] < Best)
{
    Best = Sum[2];
    iBest = 3;
    *aBits = Bits[2];
}

if (Sum[3] < Best)
{
    Best = Sum[3];
    iBest = 4;
    *aBits = Bits[3];
}

if (Sum[4] < Best)
{
    Best = Sum[4];
    iBest = 5;
    *aBits = Bits[4];
}

if (Sum[5] < Best)
{
    Best = Sum[5];
    iBest = 6;
    *aBits = Bits[5];
}

if (Sum[6] < Best)
{
    Best = Sum[6];
    iBest = 7;
    *aBits = Bits[6];
}

if (Sum[7] < Best)
{
    Best = Sum[7];
    iBest = 8;
    *aBits = Bits[7];
}

为了减少逻辑,我重写了这样的代码

for(i = 1; i < 8; i++)
{
    if(Sum[i] < Sum[index])
        index = i;
}

if (Sum[index] < Best)
{
    Best = Sum[index];
    iBest = index + 1;
    *aBits = Bits[index];
}

但是,在第二种情况下,延迟增加了大约 20%。任何人都可以对这种行为提供任何见解吗?编码风格是否if conditionsfor loopsOpenCL 更高效?

我正在使用英特尔 530 (Gen9) GPU。我正在使用内存映射访问。

4

1 回答 1

3

第一种情况对 GPU 不利。因为它强制当其中一个工作项进入 if 条件时,所有工作项都会这样做。如果您期望随机输入“if”条件,那么最后所有指令都会被执行并且它们比第二种情况更多。

而在第二种情况下,“if”中的 GPU 指令较少,只有一个衬里。并且所有工作项同时进入最后一节。

对于 CPU,第一种情况是最好的,因为不需要保存索引然后查找它。

在任何情况下,都应避免在全局内存中双重/三重读取变量。因为那些没有被编译器优化(除非标记为只读)。这段代码应该比你写的要快得多:

int best_sum = Sum[index]; //Private, fast access
for(i = 1; i < 8; i++)
{
    int sum = Sum[i]; //Again private
    if(sum < best_sum){
        index = i;
        best_sum = sum;
    }
}

if (best_sum < Best)
{
    Best = best_sum;
    iBest = index + 1;
    *aBits = Bits[index];
}
于 2017-02-28T11:04:34.357 回答