фильтр cuda с выходом этого блока является входом следующего блока - PullRequest
1 голос
/ 06 октября 2011

Работая над следующим фильтром, у меня возникла проблема с выполнением этих кодов для обработки изображения в графическом процессоре:

for(int h=0; h<height; h++) {
    for(int w=1; w<width; w++) {
    image[h][w] = (1-a)*image[h][w] + a*image[h][w-1];
    }
}

Если я определю:

dim3 threads_perblock (32, 32)

тогда каждый блок у меня: 32 темы могут быть переданы. Потоки этого блока не могут общаться с потоками из других блоков.

Внутри thread_block я могу перевести эти фрагменты кода, используя shared_memory, однако, для edge (я бы сказал): image [0,31] и image [0,32] в разных блоках потоков. Изображение [0,31] должно получить значение из изображения [0,32], чтобы вычислить его значение. Но они находятся в разных блоках.

так вот в чем проблема.

Как бы я решил это?

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 06 октября 2011

Если image находится в глобальной памяти, то проблем нет - вам не нужно использовать общую память, и вы можете просто получить доступ к пикселям напрямую из image без проблем.

Однако, если выВы уже выполнили некоторую обработку до этого, и блок image уже находится в разделяемой памяти, тогда у вас есть проблема, так как вам нужно выполнить операции соседства, которые находятся за пределами диапазона вашего блока.Вы можете выполнить одно из следующих действий: либо:

  • записать разделяемую память обратно в глобальную память, чтобы сделать ее доступной для соседних блоков (недостаток: производительность, синхронизация между блоками может быть сложной)

или:

  • обрабатывает дополнительные краевые пиксели на блок с перекрытием (в данном случае 1 пиксель), так что у вас есть дополнительные пиксели в каждом блоке для обработки краевых случаев, например, работа сразмер блока 34x34, но хранит только центральные выходные пиксели 32x32 (недостаток: требует дополнительной логики в ядре, ветви могут привести к расхождению деформации, не все потоки в блоке используются полностью)

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

0 голосов
/ 16 октября 2011

Вы можете просто использовать занятое вращение (без шуток). Просто сделайте поток обработки [32] выполнить:

while(!variable);

перед началом вычисления и обработки потока [31] do

variable = 1;

когда это закончится. Вам решать обобщить это. Я знаю, что это считается "мошенническим программированием" в CUDA, но, похоже, это единственный способ достичь того, чего вы хотите. У меня была очень похожая проблема, и она работала для меня. Ваше выступление может пострадать, хотя ... Будьте осторожны, однако, что

dim3 threads_perblock(32, 32) 

означает, что у вас 32 x 32 = 1024 потоков на блок.

...