OpenCL—缓冲区和全局内存之间的区别

OpenCL—缓冲区和全局内存之间的区别,opencl,constants,global,Opencl,Constants,Global,在Opencl中,缓冲区是从主机应用程序传输数据的管道 cl_mem clCreateBuffer (cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret); 现在如果我有一个buffera_buffer伪装成READ\u ONLY,内核是: __kernel void two_buffer_double(__global f

在Opencl中,缓冲区是从主机应用程序传输数据的管道

cl_mem clCreateBuffer (cl_context context, cl_mem_flags flags, size_t size,
                       void *host_ptr, cl_int *errcode_ret);
现在如果我有一个buffer
a_buffer
伪装成
READ\u ONLY
,内核是:

__kernel void two_buffer_double(__global float* a)
{
    int i = get_global_id(0);
    float b = a[i] * 2;
}
我的问题是:
缓冲区是全局内存还是常量内存?我是否应该使用
\u常量
限定符来表示
a
。cl_mem_标志(
只读
读写
)和内存限定符(
全局
常量
)之间有什么联系

限定符用于恒定内存,一些卡将其放入纹理缓存中,并从_全局获得独立带宽,但大小非常有限

__global __read_only * float
这意味着,如果硬件认为合适,opencl实现将尝试将其放入缓存(或使用其他数据路径),但它是全局的,因此仅受vram大小或其分数的限制,而不仅仅是64kB(例如)的常数

这些限定符用于设备端优化

在主机端优化中,您应该为它提供

CL_MEM_READ_ONLY 
作为缓冲区创建的标志。这意味着设备将只从它读取(可能使用一些DMA/PCIE访问/缓存优化),但是可以使用主机队列(使用C++或C++代码,而不是设备)编写,使用EnQueWrEngEngor或MAP UNMAP操作。
__constant
用于参数常量定义,不用于要处理的数据

如果您正在编写一个过滤器代码,那么数据可能是全局的,而过滤器掩码可能是常量的,如果它不能放入私有内存(具有最终带宽)或本地内存(比私有内存慢),那么访问掩码字节不会减少数据带宽

现在回答您的问题:

“缓冲区是全局内存还是常量内存?”

对于设备端(内核端)它是全局的,因为您将它声明为“全局”,但它可以位于主机端(硬件)的任何位置

编辑:对于主机端,取决于使用了哪些其他标志,例如,USE_host_PTR使其可直接从系统RAM访问,并且设备端只有一个虚拟缓冲区,没有虚拟缓冲区且只有一个CL_MEM_READ_WRITE设备内存将有一个真实缓冲区及其映射的阴影在RAM中(作为clenqueueread或clenqueuewrite的子步骤)和复制将首先访问此卷影,然后上载到gpu

示例设备:4GB DDR3L笔记本电脑中的Intel(R)HD(TM)GRAPHICS 400:

Query                                           value
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE                 65536 bytes
CL_DEVICE_GLOBAL_MEM_CACHE_SIZE                   262144 bytes
CL_DEVICE_GLOBAL_MEM_SIZE                     1636414260 bytes

CL_DEVICE_GLOBAL_MEM_CACHE_TYPE               CL_READ_WRITE_CACHE
CL_DEVICE_LOCAL_MEM_SIZE                      65536(vs constant, benchmark it)
CL_DEVICE_LOCAL_MEM_TYPE                      CL_LOCAL(so is faster than global)  
您无法查询私有内存大小,但对于中段游戏amd卡,每个线程组的内存大小为256kB。如果您为每个线程组设置64个线程,则每个线程可以使用4kB或其一半的寄存器空间(因为编译器优化),然后由于溢出到全局内存而变慢。

添加了有关“主机端”部分的更多信息。
Query                                           value
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE                 65536 bytes
CL_DEVICE_GLOBAL_MEM_CACHE_SIZE                   262144 bytes
CL_DEVICE_GLOBAL_MEM_SIZE                     1636414260 bytes

CL_DEVICE_GLOBAL_MEM_CACHE_TYPE               CL_READ_WRITE_CACHE
CL_DEVICE_LOCAL_MEM_SIZE                      65536(vs constant, benchmark it)
CL_DEVICE_LOCAL_MEM_TYPE                      CL_LOCAL(so is faster than global)