我正在尝试为OpenCL编写一个互斥锁。这个想法是每个单独的工作项都能够原子地进行。目前,我认为问题可能是当warp中的一个线程获得锁定时,线程warp无法继续。
我目前的简单内核,用于求和数字。 “numbers”是一个浮点数组作为输入。 “sum”是结果的一个元素数组,“semaphore”是用于保存信号量的一个元素数组。我的重点是示例here。
void acquire(__global int* semaphore) {
int occupied;
do {
occupied = atom_xchg(semaphore, 1);
} while (occupied>0);
}
void release(__global int* semaphore) {
atom_xchg(semaphore, 0); //the previous value, which is returned, is ignored
}
__kernel void test_kernel(__global float* numbers, __global float* sum, __global int* semaphore) {
int i = get_global_id(0);
acquire(semaphore);
*sum += numbers[i];
release(semaphore);
}
我正在有效地调用内核:
int numof_dimensions = 1;
size_t offset_global[1] = {0};
size_t size_global[1] = {4000}; //the length of the numbers array
size_t* size_local = NULL;
clEnqueueNDRangeKernel(command_queue, kernel, numof_dimensions,offset_global,size_global,size_local, 0,NULL, NULL);
如上所述,运行时,显卡挂起,驱动程序自行重启。我怎样才能解决这个问题呢?
答案 0 :(得分:2)
由于GPU执行模式,“处理器”上的所有线程共享指令指针,即使在分支中也是如此。这是一篇详细解释问题的帖子:http://vansa.ic.cz/author/admin/。
顺便说一下,您找到的示例代码具有完全相同的问题,并且永远不会有效。答案 1 :(得分:-1)
回想起来,答案似乎很明显,但除非你想到这一点,否则不会。
基本上,GPU对理想本地组大小(线程warp的大小)的预测大于1,因此线程warp锁定。要修复它,您只需将其指定为1(即“size_t size_local [1] = {1};”)。这样做会产生正确的结果。