2013-10-14 4 views
0

Я использую pyopencl для поиска определенного пикселя в изображении размером 512 x 512 (262,144 пикселя). Я начинаю (512 512), когда запускаю свою программу и сравниваю соседние пиксели с известной группой соседей. Я делаю синтез изображений. Я не хочу ждать, пока оставшиеся ядра будут запущены, если я найду свою группу пикселей внутри ядра. Есть ли способ закончить оставшуюся часть ядра ядра с помощью программы ядра?Как остановить все ядра 262,144, если найду свой ответ

Благодаря Тим

+0

Я думаю, что что-то не так в том, что вы называете «ядром». Вы хотите, чтобы остановить текущее ядро, когда у workitem есть результат? – DarkZeros

ответ

0

Сначала думали, что это имеет какое-то глобальный флаг памяти, что каждое ядро ​​может прочитать и установить. Такой подход требует атомарности, поэтому обязательно используйте функции atomic_.

__kernel void t(__global int *Data, 
       __global int *Flag){ 
     if(atomic_max(*Flag, 0) == 0){ 
      //perform calc on Data 
      if(PixelsFound){ 
       //Set the flag to +1 
       *Flag = atomic_inc(*Flag); 
      } 
     } 
} 

Сообщество, не стесняйтесь прокомментировать, если это известно, что это не сработало!

+1

Это может сработать, но оно будет медленным. – Dithermaster

0

Ваш вопрос - большая проблема и проблема параллелизма.

What to do when one of your parallel threads has already the answer to the problem? 

OpenCL не позволяет контролировать выполнение ядра. Даже на уровне хозяина. И это большая проблема. Однако так оно и должно быть, поскольку, если рабочие элементы не работают свободно отделяются друг от друга, то они не полностью параллельны.

Единственное решение состоит в том, чтобы разбить вычисление на мелкие части и проверить завершение каждого из них. Но иногда части уже очень маленькие (например, в вашем случае 512x512 довольно мало).

В вашем конкретном случае я бы обработал все (512x512), после чего я бы использовал другое ядро ​​для получения окончательных результатов из набора 512x512.

1

Когда вы ставите в очередь ядро ​​со многими рабочими элементами, оно делится на рабочие группы и потоки, которые заставляют GPU заняты. Действительно большие глобальные размеры запускают столько потоков, сколько могут, и выпускают новые, когда старые заканчиваются. Таким образом, вы можете найти наименьший глобальный размер, который все еще хорошо работает, и ставить в очередь многие из них (вместо одного большого), но также проверять результаты предыдущих, которые вы поставили в очередь (использовать события, чтобы знать, когда они сделаны, и читайте назад память, чтобы получить их результаты). Когда вы получите правильный ответ, остановите ядра очереди.

так вместо этого:

queue entire job (say, 4096 x 4906) 

сделать:

do 
{ 
    queue some work (say, 32 x 32) 
    check if any of the prior work queued is done and check if it got the answer 
} 
while (no more work OR answer found) 

Вам нужно выяснить правильный компромисс между размером небольших рабочих мест и накладными расходами на проверку их результатов в сравнении дополнительная работа сделана.