【问题标题】:Size of pointer on GPU vs. size of pointer on CPUGPU 上的指针大小与 CPU 上的指针大小
【发布时间】: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


    【解决方案1】:
    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,这是一个附加扩展,则可以将主机指针直接传递给设备,例如在其他数据结构中。

    【讨论】:

      【解决方案2】:

      你能举例说明你将如何使用它吗?

      这样的结构对于双方的使用基本上都是无稽之谈,因为你不能将指针传递给另一个 cl_mem 中的一个 cl_mem。

      【讨论】:

      • 所以,你是对的!它没有意义,因为它没有用,但是如果我有一个像 typedef struct { __global float4* ptr; } my_struct_gpu; 这样的结构,我想在我的内核参数中使用它,比如 __kernel void mykernel(__global my_struct_gpu data),我应该在主机端为 data 分配内存。我想知道我应该为 gpu 上的指针对象分配多少内存。是和CPU(4bytes)一样还是不一样?
      【解决方案3】:

      主机端:

        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 类型,那么您不应该直接发送它们。

      【讨论】:

        【解决方案4】:

        无法保证设备上的指针大小与主机上的大小相同。因此,也不能保证结构的大小相同。

        通过使用clGetDeviceInfoCL_DEVICE_ADDRESS_BITS 作为param_name,可以在运行时请求特定设备指针的使用大小。 OpenCL 规范对返回值有如下说明。

        默认计算设备地址空间大小指定为无符号整数值(以位为单位)。当前支持的值为 32 位或 64 位。

        我测试的机器使用 64 位大小的指针,而为 GPU 返回 32 位。所以在这种情况下,结构的大小会不同。

        【讨论】:

        • 是的。 cl_float4 和 float4 应该具有相同的大小,但问题是指向 cl_float 的指针是否具有相同大小的指向 cpu 和 gpu 上的 float4 的指针?例如在 C++ 中,一个指针占用 4 个字节,
        猜你喜欢
        • 1970-01-01
        • 2011-04-20
        • 2010-12-07
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        • 2013-01-13
        相关资源
        最近更新 更多