【发布时间】:2015-03-27 14:16:59
【问题描述】:
我在设备端定义一个结构。它在 GPU 和 CPU 上的大小会相同吗?
主机端:
typedef struct {
cl_float4* ptr;
} my_struct_cpu;
设备端:
typedef struct {
float4* ptr;
} my_struct_gpu;
【问题讨论】:
标签: c pointers opencl address-bus
我在设备端定义一个结构。它在 GPU 和 CPU 上的大小会相同吗?
主机端:
typedef struct {
cl_float4* ptr;
} my_struct_cpu;
设备端:
typedef struct {
float4* ptr;
} my_struct_gpu;
【问题讨论】:
标签: c pointers opencl address-bus
typedef struct {
cl_float4* ptr;
} my_struct_cpu;
在这种情况下,主机指针将是 sizeof(int*) == sizeof(cl_float4*),它将映射到 4 或 8 个字节,具体取决于您的应用程序是以 32 位还是 64 位编译的。如果您在非移动设备上,最有可能是 64 位,在智能手机上可能是 32 位或 64 位,尽管这种情况正在发生变化。
typedef struct {
float4* ptr;
} my_struct_gpu;
sizeof(int*) == sizeof(float4*) 在设备上,同样可以是 32 位或 64 位,但是,对于 OpenCL 1.x,主机指针和设备指针的大小不需要相同事实上,GPU 是 32 位的 pointers.h 是很常见的 对于 OpenCL 2.x,情况可能并非如此。特别是 OpenCL 2.0 在 CPU 和 GPU 之间引入了共享虚拟内存,作为扩展,如果给定的 OpenCL 平台支持这一点,那么主机和设备指针的大小确实是相同的。此外,如果支持全细粒度 SVM,这是一个附加扩展,则可以将主机指针直接传递给设备,例如在其他数据结构中。
【讨论】:
你能举例说明你将如何使用它吗?
这样的结构对于双方的使用基本上都是无稽之谈,因为你不能将指针传递给另一个 cl_mem 中的一个 cl_mem。
【讨论】:
typedef struct { __global float4* ptr; } my_struct_gpu; 这样的结构,我想在我的内核参数中使用它,比如 __kernel void mykernel(__global my_struct_gpu data),我应该在主机端为 data 分配内存。我想知道我应该为 gpu 上的指针对象分配多少内存。是和CPU(4bytes)一样还是不一样?
主机端:
typedef struct {
cl_float4* ptr;
} my_struct_cpu;
float * SerializeForPcieSend(my_struct_cpu [] p){...}
发送到gpu:
array_of_floats_widthx4 -----> enqueuewritebuffer
gpu 端:接收和构建 cl 端结构:
__kernel void BuildStructs(__global float * structArr, __global my_struct_gpu * structs_in_gpu)
{
.... copies, computes, builds
}
然后 gpu 对这个新数据进行计算
__kernel void BuildStructs(__global my_struct_gpu * structs_in_gpu, __global float * responseArray)
{
.... computes, extracts elements and puts in response array
}
主机端:然后cpu取结果
clenqueuereadbuffer
array_of_floats_widthx4 <------------- response array
不要忘记使用 sizeof(cl_float)*num_elements 仔细检查缓冲区读取和写入的大小。
然后重新构建主机端对象
my_struct_cpu * DeserializeAfterPcieDownload(float * p){...}
简短回答:不,并非总是如此。但是如果你将更大的元素放在结构的上侧并且字节顺序相同,那么对于某些 gpus 应该没有问题。如果有 float3 类型,那么您不应该直接发送它们。
【讨论】:
无法保证设备上的指针大小与主机上的大小相同。因此,也不能保证结构的大小相同。
通过使用clGetDeviceInfo 和CL_DEVICE_ADDRESS_BITS 作为param_name,可以在运行时请求特定设备指针的使用大小。 OpenCL 规范对返回值有如下说明。
默认计算设备地址空间大小指定为无符号整数值(以位为单位)。当前支持的值为 32 位或 64 位。
我测试的机器使用 64 位大小的指针,而为 GPU 返回 32 位。所以在这种情况下,结构的大小会不同。
【讨论】: