如何读取结构数组(OpenCL内核)

时间:2018-01-20 17:45:19

标签: opencl

要求:

假设我们有1)五组颜色,每组有三种颜色(颜色是在CPU中动态生成的)和2)1000辆汽车的列表,每辆汽车的颜色在列表中表示(从小组中挑选的颜色)。 我们想要将三个参数传递给OpenCL内核:1)一组生成的颜色,2)汽车的颜色数组(1D),以及3)整数数组(1D)来测试汽车颜色颜色组(进行简单的计算)。

结构:

struct GeneratedColorGroup
{
   float4 Color1; //16 =2^4
   float4 Color2; //16 =2^4
   float4 Color3; //16 =2^4
   float4 Color4; //16 =2^4
}

struct ColorGroup
{
    GeneratedColorGroup Colors[8]; //512 = 2^9
}

内核代码:

__kernel void findCarColorRelation(
const __global ColorGroup *InColorGroups,
const __global float4* InCarColor,
const __global int* CarGroupIndicator
const int carsNumber)
{
    int globalID = get_global_id( 0 );
    if(globalID < carsNumber)
    {
        ColorGroup colorGroups;
        float4 carColor;
        colorGroups = InColorGroups[globalID];
        carColor = InCarColor[globalID];

        for(int groupIndex =0; groupIndex < 8; groupIndex++)
        {
            if(colorGroups[groupIndex].Color1 == carColor)
            {
                CarGroupIndicator[globalID] = groupIndex + 1 ;
                break;
            }

            if(colorGroups[groupIndex].Color2 == carColor)
            {
                CarGroupIndicator[globalID] = groupIndex * 2 + 2;
                break;
            }

            if(colorGroups[groupIndex].Color3 == carColor)
            {
                CarGroupIndicator[globalID] = groupIndex * 3 + 3;
                break;
            }
        }
    }

}

现在,我们有1000个项目,这意味着内核将被执行1000次。没关系。

问题: 如你所见,我们有一个全局ColorGroup作为内核的输入,这个全局内存有五个&#34; GeneratedColorGroup&#34;类型。

我试图访问这些项目,如上面的代码所示,但我得到了意想不到的结果。并且执行非常缓慢。

我的代码有什么问题? 任何帮助都非常感谢。

2 个答案:

答案 0 :(得分:1)

将结构从主机传递到设备时,请确保在主机和设备代码中使用__attribute__ ((packed))声明结构类型。否则,主机和设备编译器可能会为结构创建不同的内存布局,即它们可以使用不同的大小进行填充。

使用打包的结构可能会导致性能降级,因为打包的结构根本没有填充,因此结构中的数据可能无法正确对齐,并且未对齐的访问通常很慢。在这种情况下,您必须手动插入带有char[]的填充,或者在结构字段(或结构本身)上使用__attribute__ ((aligned (N)))

有关packedaligned属性的详细信息,请参阅OpenCL C规范: https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/attributes-types.html

答案 1 :(得分:0)

我疯狂猜测问题是

... CarGroupIndicator[globalID] = groupIndex + 1 ;
... CarGroupIndicator[globalID] = groupIndex * 2 + 2;
... CarGroupIndicator[globalID] = groupIndex * 3 + 3;

...这使得无法从结果CarGroupIndicator[globalID]中确切地说明匹配的内容。例如。第5组颜色1的匹配结果为值6,但第2组颜色2和第1组颜色3结果也是值6.您想要的是这样的:

... CarGroupIndicator[globalID] = groupIndex;
... CarGroupIndicator[globalID] = groupIndex + 8;
... CarGroupIndicator[globalID] = groupIndex + 16;

..然后0-7是color1,8-15 color2,16-24 color3。