Memory opencl使用情况下的错误信号量

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之间写入缓冲区 不要忘记全局变量必须是可变的 当

解决方案:

最后,我可以解决问题,或者至少为我的问题找到一个好的解决办法。 这种信号灯在NVIDIA中不起作用。 我认为这个评论是对的

所以我决定使用原子添加(),这是OpenCL1.1的必备部分。 我有一个resultBuffer数组和resultBufferSize全局变量,最后一个变量设置为零

当我有结果时(我的结果总是!!x个数字),我会简单地调用 位置=原子添加(结果缓冲大小,x) 我可以确定没有人在position和position+x之间写入缓冲区

不要忘记全局变量必须是可变的

当线程运行到无限循环中时,资源不可用,因此在缓冲区读取期间会出现-5错误代码

更新:

当我回读时:

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
缓冲区?如果不是的话,看起来这里会有一个无限循环。