2012-02-09 1 views
2

Я снимаю видеокадры. Каждый кадр передается в ядро ​​как Image2D. У меня есть около пяти простых алгоритмов обработки изображений (размытие, резкость и т. Д.), Которые пользователь может выбрать (также возможно сочетание разных). Я вижу три возможности здесь:Как обрабатывать переменное число алгоритмов в ядре?

  1. Одно ядро: Во время выполнения построить строку ядра с выбранных алгоритмов и компиляции (и взять на себя нагрузку от одного времени компиляции задержки)
  2. Одно ядро: Обрабатывать выбранные алгоритмы с флагами (хотя я понимаю, что условные ветви нежелательны)
  3. Многие ядра (по одному на алгоритм): Кажется, вопрос, что Image2D может быть либо read_only или write_only, и я должен был бы repetively скопировать изображения с и на GPU, поскольку один выходной образ ядра является i nput образ следующего ядра.

Есть ли предлагаемое эмпирическое правило, каким образом следовать?

+0

Относительно условного исполнения: вид ветвления, о котором вы говорите, вероятно, не так уж плох. Каждый рабочий элемент по-прежнему идет по тому же пути для выполнения данного ядра. Это ситуации, когда разные рабочие элементы разветвляются в разных направлениях, что действительно убьет вашу производительность. – James

+0

Спасибо Джеймсу, я его оценю. – rdoubleui

ответ

2

Одним из способов решения проблемы с readonly/writeonly может быть использование буферов для средних шагов.

Image2D -> buffer0 -> buffer1 -> ... bufferN -> Image2D

Или использовать два буфера и чередуются с ними, если вам не нужны промежуточные результаты. (I2d, B0, B1, B0, ..., I2D)

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

+0

Интересные мысли. Ну, в этом случае достаточно одного буфера, так как алгоритмы применяются последовательно. – rdoubleui

+0

Я, конечно, ошибался в одном буфере. Вам нужно как минимум два буфера внутри. – rdoubleui

+1

Я пошел с этим подходом и нашел его более элегантным. Однако в одном ядре все еще существует упомянутое ветвление, однако ветка ведет к одному и тому же пути для всех рабочих элементов.Я приурочил его, и это не имело никакого значения. – rdoubleui

1

Я полагаю, что вы пытаетесь избежать первые два варианта

  1. Таким образом, вы будете иметь очень нечитаемый и сложный код ядра. это нормально, если вы на 100% уверены, что код выполняет то, что он должен делать. То есть с учетом договоренности и группировки ваших рабочих предметов. Дело в том, что это будет сложно и отлаживать и поддерживать ваши ядра таким образом.

  2. Это, я думаю, даже хуже, чем первый вариант, если ваши потоки могут идти по разным путям. Простое ветвление может снизить ваши характеристики и создать проблемы для синхронизации. В ДОПОЛНЕНИИ к простому ветвлению вы должны учитывать тот факт, что вашим алгоритмам может потребоваться различное количество и расположение потоков. Если это так, то использование одного ядра для всех операций - это действительно плохая идея.

Я не пробовал это сам, но я думаю, вам стоит попробовать вариант, предложенный @mfa.

+0

Взгляните на комментарий Джеймса: он предполагает, что второй способ может быть не таким уж плохим, поскольку все рабочие элементы по-прежнему идут по тому же пути. Ядро отличается только между кадрами, где новое ядро ​​находится в очереди для выполнения перед каждым фреймом. Я расскажу, к чему в конечном итоге привели мои попытки. – rdoubleui

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