2

我正在尝试为 OpenCL 编写互斥锁。这个想法是让每个单独的工作项都能够以原子方式进行。目前,我认为问题可能是当扭曲中的一个线程获得锁时线程扭曲无法继续进行。

下面是我当前的简单内核,用于对数字求和。“数字”是一个浮点数组作为输入。“sum”是结果的单元素数组,“semaphore”是保存信号量的单元素数组。我在很大程度上基于此处的示例。

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);

如上,运行时显卡挂起,驱动自行重启。我怎样才能修复它,使它不会?

4

2 回答 2

2

由于 GPU 执行模型,您尝试做的事情是不可能的,其中“处理器”上的所有线程共享指令指针,即使在分支中也是如此。这是一篇详细解释该问题的帖子:http: //vansa.ic.cz/author/admin/

顺便说一句,您找到的示例代码具有完全相同的问题,并且永远不会工作。

于 2013-01-25T13:03:31.810 回答
-1

回想起来,这个问题的答案似乎很明显,但除非你想到它,否则它不是。

基本上,GPU 对理想局部组大小(线程扭曲的大小)的预测大于 1,因此线程扭曲锁定。要修复它,您只需将其指定为 1(即“size_t size_local[1] = {1};”)。这样做会产生正确的结果。

于 2013-01-18T03:24:45.000 回答