Должен ли я создать несколько ядер OpenCL, чтобы избежать условных выражений?
-
29-09-2019 - |
Вопрос
В OpenCL у меня есть ядро, которое должно работать со сложными и реальными данными.Я мог бы поместить условный оператор, который вызывает нужную строку кода для обработки этого, или у меня могло бы быть два ядра, которые я вызываю, и передать условный оператор в мой вызывающий код.
Очевидно, что это плохо сказывается на ремонтопригодности, но существенно ли это для производительности?
Решение
Если это всего лишь одно условное утверждение, по моему опыту, разница в производительности абсолютно незначительна, по крайней мере, на оборудовании nvidia.
По сути, до тех пор, пока все (или большинство) рабочих элементов следуют по одному пути кода, все в порядке. Поскольку путь кода зависит от аргумента ядра в вашем случае, все рабочие элементы следуют по одному пути.
Другие советы
Слегка зависит от того, где условный. Код для чтения первым, то производительность после того, как вы измерили его и обнаружили, что это проблема
например. KERNEL_FOR_RGB_IMAGE и KERNEL_FOR_ABGR_IMAGE кажется разумным использованием, различные ядра для эффективного развертывания некоторой глубокой внутренней петли могут быть большей головной болью.
Я думаю, что лучший способ - это действительно попробовать сравнить два варианта.В некоторых случаях компиляция нескольких условных блоков, даже если выполняется только один из них, может привести к снижению производительности.Причина в GPRs (регистрах общего назначения):компилятор выделяет столько регистров, сколько необходимо для наихудшего случая.
Я могу предложить такое решение:иметь единственную функцию ядра, но с условием времени компиляции:
__kernel void work()
{
#if VAR
// one code
#else
// another code
#endif
}
Затем вам нужно перекомпилировать ядро с помощью true
/false
установлено значение VAR
при изменении состояния.Очевидно, что для компилятора это не отличается от двух ядер, но для поддержки может быть лучше, если часть кода будет одинаковой для этих ядер.