2014-06-30 33 views
2

我用C++包装,并用下面的代码创建缓冲区:为什么clCreateBuffer使用主机内存?

cl_int err(0); 
unsigned int size; 
void *data = GetData(/*out*/ size); 

cl::Buffer buf(m_ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, 
     size, data, &err); 

free(data); 

之后工作由size字节设定的我的应用程序的增加。而且,由于我有32位应用程序,因此总共不能分配更多的1.5 Gb,但GPU有3 Gb。

是否可以分配更多缓冲区?

PS。 size小于128 Mb。

更新:我只使用1个设备,它是GPU。 (GeForce GTX 780 GPU NVIDIA Corporation 337.88)

+0

我必须问:难道你有多个平台和/或设备,并且意外地选择了** CPU **作为工作设备(而不是** GPU **)? – Marco13

+1

'CL_MEM_COPY_HOST_PTR'可能会触发某些固定的行为。禁用它支持正常的'clEnqueueWriteBuffer()'可能会解决这个问题。如果不是这样,那么司机是如何在较低级别工作的,并且可能无法改变行为。 – DarkZeros

+0

@DarkZeros通常,'CL_MEM_COPY_HOST_PTR'不应该导致锁定(与CL_MEM_USE_HOST_PTR'相反),但是您可能比我更了解细节,并且有疑问的是,这种行为取决于OpenCL的实现。 (至少,规范中可能没有任何内容阻止实现锁定内存......) – Marco13

回答

0

我不知道问题发生的确切原因,它可能是一些潜在的驾驶员行为。

但是,禁用特殊标志似乎可以为nVIDIA平台解决问题,也可能为AMD解决问题。所以我正在写一个正确的答案。

cl_int err(0); 
unsigned int size; 
void *data = GetData(/*out*/ size); 

cl::Buffer buffer = cl::Buffer buf(m_ctx, CL_MEM_READ_WRITE, 
     size, NULL, &err); 
err = queue.EnqueueWriteBuffer(buffer, CL_TRUE, NULL, size, data); 

free(data); 
0

部分回答您的问题。内存块的最大尺寸,可以分配:

cl_ulong max_buffer_size = 0; 

cl_int ret_code = clGetDeviceInfo(Device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, 
    sizeof(cl_ulong), &max_buffer_size, NULL); 

if(ret_code != CL_SUCCESS){ 
    fprintf(stderr, "Error %d happened \n", ret_code); 
} 

一般的OpenCL API不允许分配大(超过几百兆字节)的内存对象。

+0

我没有分配大量内存对象,我分配了许多小对象。 –

+0

好吧,我明白了。在总共1.5 Gb之后,您是否收到任何特定的错误/例外情况? –

+0

不,我只是没有更多的内存来分配我的过程。但是,当我使用'clEnqueueWriteBuffer()'绕过这个限制时,我得到了BSOD =(。 –

0

DarkZeros在评论中是正确的。它似乎是依赖于实现的,当我使用clEnqueueWriteBuffer()而不是标记CL_MEM_COPY_HOST_PTR时,它解决了问题。

相关问题