Эффективное декодирование RLE в CUDA

Мне нужно декодировать RLE в CUDA, и я пытался подумать о наиболее эффективном способе расширения RLE в список со всеми моими значениями. Итак, скажем, мои значения равны 2, 3, 4, а мои прогоны - 3, 3, 1. Я хочу расширить это до 2, 2, 2, 3, 3, 3, 4.

Сначала я думал, что могу использовать cudaMemset, но теперь я почти уверен, что это запускает ядро, и у меня есть CUDA Compute Capability 3.0, поэтому, даже если запуск нового ядра для каждой пары значение / запуск, вероятно, не будет неэффективным, у меня нет динамического параллелизма доступны для этого.

Поэтому я хочу знать, правильно ли это решение, прежде чем я пойду и реализую его, поскольку есть так много вещей, которые в конечном итоге не работают на CUDA, если вы не умны. Было бы разумно сделать ядро, которое будет вызывать cudaMalloc, а затем cudaMemCpy к месту назначения? Я могу легко вычислить суммы префиксов, чтобы знать, куда копировать память и откуда, и сделать так, чтобы все мои чтения были, по крайней мере, объединены. Что меня беспокоит, так это то, что я так часто звоню cudaMalloc и cudaMemCpy.

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


person flips    schedule 18.04.2016    source источник


Ответы (2)


Вы не хотите думать о выполнении отдельной операции (например, cudaMalloc или cudaMemset) для каждой пары значение/выполнение.

После вычисления суммы префиксов в последовательности выполнения последнее значение в сумме префиксов будет общим размером выделения. Используйте это для одной операции cudaMalloc для всей финальной расширенной последовательности.

После того, как вы выделили необходимое пространство и вычислили сумму префиксов, фактическое расширение становится довольно простым.

thrust может сделать это довольно легко, если вам нужен быстрый прототип. Для этого есть пример кода.

person Robert Crovella    schedule 18.04.2016
comment
Роберт, ты один из самых замечательных людей вокруг. Вы решили все проблемы, с которыми я когда-либо сталкивался в CUDA. Благодарю вас! - person flips; 18.04.2016

@RobertCrovella, конечно, прав, но вы можете пойти еще дальше с точки зрения эффективности, если у вас есть возможность немного изменить схему сжатия.

Извините за самоподключение, но вам может быть интересна моя собственная реализация варианта Run-Length Encoding с добавлением привязки выходных позиций к входным (например, «в каком смещении в какой серии у нас есть 2048-й элемент?»); это позволяет более справедливо распределять работу по блокам потоков и устраняет необходимость в полномасштабной сумме префиксов. Он все еще находится в стадии разработки, поэтому на момент написания я получаю только около 34 ГБ/сек на карте с пропускной способностью памяти 336 ГБ/сек (Titan X), но ее вполне можно использовать.

person einpoklum    schedule 16.02.2017