欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

OpenCL心得2

程序员文章站 2024-01-01 14:18:40
...

1.clEnqueueNDRangeKernel函数错误( Access violation reading location 0x000......... ) 后来发现原来是设置参数的时候搞疏忽掉了: mem = clCreateBuffer(context, CL_MEM_READ_WRITE, VectorLength, 0, err); clSetKernelArg(gpus[i].kernel, argIdx,

1.clEnqueueNDRangeKernel函数错误(Access violation reading location 0x000.........

后来发现原来是设置参数的时候搞疏忽掉了:

mem = clCreateBuffer(context, CL_MEM_READ_WRITE, VectorLength, 0, &err);

clSetKernelArg(gpus[i].kernel, argIdx++, sizeof(cl_mem), mem);


这里的mem应当传递指针,而不是值,改成这样即可:

mem = clCreateBuffer(context, CL_MEM_READ_WRITE, VectorLength, 0, &err);

clSetKernelArg(gpus[i].kernel, argIdx++, sizeof(cl_mem), &mem);


这个问题只是疏忽和粗心导致的,而且它还不怎么好找到。



2.使用GPU所有显存资源和关于GPU寻址问题的解答

使用openCL时发现,GPU显存6GB,地址长度是32bit的,CL_DEVICE_MAX_MEM_ALLOC_SIZE是1GB,我就感到很怀疑,地址才32bit,它要如何寻址呢,怎么使用到6GB显存呢?


后经过实践发现,GPU的显存是根据上下文来分配的,也就是你需要对6GB显存创建6个上下文,每个上下文分别分配1GB内存即可。而不是在一个上下文里面分配6次1GB内存。所以说之前所怀疑的GPU寻址根本就不是个问题。当然,这个是说的理论,实际情况下你还得考虑是否有其他地方有使用显存(比如有的GPU启用ECC的情况下,会有12.5%的空间做ECC用,所以实际可以使用的空间只有87.5%),如果有的话,很明显就不可能使用所有的资源,在clEnqueueNDRangeKernel函数的时候会报CL_OUT_OF_RESOURCES错误的.


这个问题也说明的我对GPU内存模型缺少认识,当初在网上也没有找到能够说明这个的资料。最终还是自己实践来得最直接。



3.CL_MEM_OBJECT_ALLOCATION_FAILURE错误

首先得需要了解下GPU显存分配的时间。

a.当你执行clCreateBuffer函数的时候,你可以查看GPU-Z的显示,可以发现GPU的显存并没有占用。实际上你查看taskmgr,会发现内存使用却增加了。也就是执行clCreateBuffer的时候仅仅是在内存里面分配一块跟你要分配的数据一样大的内存,并且把数据Copy过去。所以这个时候他只会检查你想要分配的显存尺寸有没有超过CL_DEVICE_MAX_MEM_ALLOC_SIZE的限制,而不会去到GPU里面检查剩余空间够不够。

b.根据a你可以发现,一切显存的分配都发生在clEnqueueNDRangeKernel函数的时候,当你执行这个函数的时候,GPU的显存和使用率都起来了。也就在这个时候,如果GPU显存不够放你分配的显存的时候,问题就来了。一旦尺寸超过了,则会报CL_MEM_OBJECT_ALLOCATION_FAILURE错误,所以出现CL_MEM_OBJECT_ALLOCATION_FAILURE的时候,你应该检查clCreateBuffer创建的尺寸是否得当。

上一篇:

下一篇: