2013-09-27 2 views
0

Я следую this учебник, который отлично работает, за исключением самого последнего примера того, как создать семафор, не работает для меня. Логика довольно проста, но я не могу понять, почему это ядро ​​приводит к бесконечному циклу.Как предотвратить тупик в семафоре OpenCL?

myKernel.cl

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable 
void GetSemaphor(__global int * semaphor, __global int * data) { 
    int occupied = atom_xchg(semaphor, 1); 
    int realityCheck = 0; 
    while(occupied == 1 && realityCheck++ < 100000) 
     occupied = atom_xchg(semaphor, 1); 
} 

void ReleaseSemaphor(__global int * semaphor) 
{ 
    int prevVal = atom_xchg(semaphor, 0); 
} 

__kernel void myKernel(__global int* data, __global int* semaphor) 
{ 
    // semaphor[0] is set to 0 on the host. 
    GetSemaphor(&semaphor[0], data); 
    data[0]++; 
    ReleaseSemaphor(&semaphor[0]); 
} 

Это с:

OpenCL 1.2

FULL_PROFILE

на Quadro NVS 290, который имеет

* cl_khr_global_int32_base_atomics кл _khr_global_int32_extended_atomics

ответ

2

Этот урок, который вы используете, неверен и никогда не будет работать на устройствах GPU. Благодаря архитектуре HW.

Любой механизм синхронизации, который блокирует работу внутри рабочей группы, просто не работает. Поскольку состояние блокировки влияет на всю рабочую группу, создается бесконечный цикл.

Вы можете делать только такие вещи с размером рабочей группы 1. Или через рабочие группы.

+0

хороший ответ, спасибо! – user1873073

+1

Согласовано. Проблема заключается в том, что первый рабочий элемент получает семафор, и тогда ни один из остальных рабочих элементов не может продолжаться, за исключением того, что в большинстве архитектур ряд рабочих элементов привязан к основному или волновому фронту и должен действовать в режиме блокировки , поэтому, блокируя другие рабочие элементы, вы заблокировали весь warp/wavefront, который блокирует рабочую группу, которая блокирует ваше ядро. – Dithermaster

Смежные вопросы