1

当将一个结构数组作为参数传递给我的内核时,我得到第一个之后的项目的奇怪值(数组 [1]、数组 [2] 等)。这似乎是一个对齐问题,也许?

这是结构:

typedef struct Sphere
{
    float3 color;
    float3 position;
    float3 reflectivity;
    float radius;
    int phong;
    bool isReflective;
} Sphere;

这是主机端的初始化代码:

cl::Buffer cl_spheres = cl::Buffer(context, CL_MEM_READ_ONLY, sizeof(Sphere) * MAX_SPHERES, NULL, &err);
err = queue.enqueueWriteBuffer(cl_spheres, CL_TRUE, 0, sizeof(Sphere) * MAX_SPHERES, spheres, NULL, &event);
err = kernel.setArg(3, cl_spheres);

发生的情况是,数组中第二个 Sphere 结构的颜色实际上将具有我在主机端(s3 或 z)设置颜色的最后一个值、一个未初始化的零值和我设置的第一个值位置到主机端(s0 或 x)。我注意到 float3 数据类型实际上仍然有第四个值(s3)没有被初始化。我认为这就是非初始化零值的来源。因此,这似乎是一个对齐问题。我真的不知道我能做些什么来解决它。我希望也许有人可以阐明这个问题。我确保我的结构定义在两边都完全相同。

4

1 回答 1

1

从 OpenCL 1.2 规范,第 6.11.1 节:

请注意,ISO C 标准要求任何给定结构或联合类型的对齐至少是相关结构或联合的所有成员的对齐的最小公倍数的完美倍数,并且还必须是两个的幂。

cl_float3算作 a cl_float4,见 6.1.5 节。

最后,在第 6.9.k 节中:

程序中内核函数的参数不能使用内置标量类型 bool、half、size_t、ptrdiff_t、intptr_t 和 uintptr_t 或包含声明为这些内置标量类型之一的字段的结构和/或联合声明.

为了遵守这些规则,并且可能使访问速度更快,您可以尝试(OpenCL C 端;在主机上使用cl_float4):

typedef struct Sphere
{
    float4 color;
    float4 position;
    float4 reflectivity;
    float4 radiusPhongReflective; // each value uses 1 float
} Sphere;
于 2012-04-16T20:20:51.553 回答