OpenCL 内核是用类似 C99 的受限制(例如,结构中没有指针)和扩展(例如 float4 数据类型)语言编写的。它们不是用 C++ 编写的。
您在主机上初始化类似 C 的结构,然后将它们复制过来。类似 C 的结构没有方法。在带有 Visual Studio 的主机上使用 C++ OpenCL 绑定(来自 cl.hpp)我执行以下操作:
#pragma pack(16)
struct Light {
cl_float4 pos;
cl_float4 dir;
cl_float4 intensity;
cl_int type;
cl_int pad[3];
};
#pragma pack()
const int nlight = 10
Light lights[nlight];
//...code to initialize array of structs
cl::Buffer lights_mem = cl::Buffer(context, CL_MEM_COPY_HOST_PTR, sizeof(Light)*nlight, lights);
kernel1.setArg(0, lights_mem);
这会将灯光复制到 OpenCL 设备。在内核中,您可以像这样访问灯光结构:
__kernel void trace(__global Light* lights, ...) {
float4 pos = lights[0].pos
//find a new position (pos_new)
lights[0].pos = pos_new;
当内核完成时,您可以将 cl::Buffer lights_mem 传递给下一个内核。
kernel2.setArg(0, lights_mem);
但是,您可以通过使用只读或只写缓冲区来获得更好的速度,因此将内核分为只读和只写可能会有所帮助。
我不知道 pack() pragma 和 padding 是否仍然是必要的,但我一直在使用它们,因为每次有人说它们不再需要时,我都会遇到一个问题,当我把它们放回去时就会消失。