Memory opencl使用情况下的错误信号量
解决方案: 最后,我可以解决问题,或者至少为我的问题找到一个好的解决办法。 这种信号灯在NVIDIA中不起作用。 我认为这个评论是对的 所以我决定使用原子添加(),这是OpenCL1.1的必备部分。 我有一个resultBuffer数组和resultBufferSize全局变量,最后一个变量设置为零 当我有结果时(我的结果总是!!x个数字),我会简单地调用 位置=原子添加(结果缓冲大小,x)强> 我可以确定没有人在position和position+x之间写入缓冲区 不要忘记全局变量必须是可变的 当线程运行到无限循环中时,资源不可用,因此在缓冲区读取期间会出现-5错误代码 更新: 当我回读时:Memory opencl使用情况下的错误信号量,memory,visual-studio-2013,opencl,mutex,nvidia,Memory,Visual Studio 2013,Opencl,Mutex,Nvidia,解决方案: 最后,我可以解决问题,或者至少为我的问题找到一个好的解决办法。 这种信号灯在NVIDIA中不起作用。 我认为这个评论是对的 所以我决定使用原子添加(),这是OpenCL1.1的必备部分。 我有一个resultBuffer数组和resultBufferSize全局变量,最后一个变量设置为零 当我有结果时(我的结果总是!!x个数字),我会简单地调用 位置=原子添加(结果缓冲大小,x) 我可以确定没有人在position和position+x之间写入缓冲区 不要忘记全局变量必须是可变的 当
oclErr |= clEnqueueReadBuffer(cqCommandQueue, cm_inputNodesArraySizes, CL_TRUE, 0, lastMapCounter*sizeof(cl_uint), (void*)&inputNodesArraySizes, 0, NULL, NULL);
lastMapCounter的值将更改。这很奇怪,因为在ocl代码中,我什么都不做,而且我关心大小:我在缓冲区创建中写入的内容和复制的内容都是一样的。一个隐藏的缓冲区溢出确实会导致很多问题
更新结束
我做了下面的代码,其中有一个bug。我需要一个信号量来更改resultBufferSize全局变量(现在我只想尝试它的工作方式)并返回一个大数字(假设每个工作人员都写了一些东西)。但我总是有3个或3个错误。编译器如何工作没有逻辑
__kernel void findCircles(__global uint *inputNodesArray, __global
uint*inputNodesArraySizes, uint lastMapCounter,
__global uint *resultBuffer,
__global uint *resultBufferSize, volatile __global uint *sem)
{
for(;atom_xchg(sem, 1) > 0;)
(*resultBufferSize) = (*resultBufferSize) + 3;
atom_xchg(sem, 0);
}
在内核执行期间,我得到了-48,有时还可以,当我想读回缓冲区(大小缓冲区)时,我得到了-5
你知道我在哪里能找到窃听器吗
使用的NVIDIA opencl 1.1
当然,在主机上,我可以很好地配置所有内容:
uint32 resultBufferSize = 0;
uint32 sem;
cl_mem cmresultBufferSize = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE,
sizeof(uint32), NULL, &ciErrNum);
cl_mem cmsem = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE, sizeof(uint32), NULL,
&ciErrNum);
ciErrNum = clSetKernelArg(ckKernel, 4, sizeof(cl_mem), (void*)&cmresultBufferSize);
ciErrNum = clSetKernelArg(ckKernel, 5, sizeof(cl_mem), (void*)&cmsem);
ciErrNum |= clEnqueueNDRangeKernel(cqCommandQueue, ckKernel, 1, NULL,
&szGlobalWorkSize, &szLocalWorkSize, 0, NULL, NULL);
ciErrNum = clEnqueueReadBuffer(cqCommandQueue, cmresultBufferSize, CL_TRUE, 0,
sizeof(uint32), (void*)&resultBufferSize, 0, NULL, NULL);
(对于这段代码,内核是正常的,最后一次读取是return-5)我知道您已经得出了一个结论,但我想指出两件事: 1) 正如链接线程中指出的,信号量是不可移植的,因为它不是SIMD安全的。
2) 内存模型不够强大,无法赋予代码意义。结果缓冲区的更新可能会移出关键部分-模型中没有其他说明。至少您需要fences,但是1.x规范中围绕fences的语言也相当弱。您需要一个OpenCL2.0实现来确保这方面是安全的。您是否用零值初始化
cmsem
缓冲区?如果不是的话,看起来这里会有一个无限循环。