OpenCL—缓冲区和全局内存之间的区别
在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
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 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)