Подтвердить что ты не робот

Должен ли я объединить два похожих ядра с выражением "if", рискуя потерями производительности?

У меня есть две очень похожие функции ядра, в том смысле, что код почти тот же, но с небольшой разницей. В настоящее время у меня есть 2 варианта:

  • Напишите два разных метода (но очень похожих)
  • Напишите одно ядро ​​и поместите блоки кода, которые отличаются в инструкции if/else

Сколько будет выполняться оператор if, влияющий на производительность моего алгоритма?
Я знаю, что нет ветвления, поскольку все потоки во всех блоках будут вводить либо if, либо else.
Так будет ли один оператор if уменьшать мою производительность, если функция ядра вызывается много раз?

4b9b3361

Ответ 1

У вас есть третий вариант, который должен использовать шаблоны С++ и сделать переменную, которая используется в инструкции if/switch для параметра шаблона. Создайте каждую версию ядра, в которой вы нуждаетесь, а затем у вас есть несколько ядер, которые делают разные вещи без разлуки ветвей или условной оценки, о которых нужно беспокоиться, потому что компилятор оптимизирует прочь мертвый код и разветвление с ним.

Возможно, что-то вроде этого:

template<int action>
__global__ void kernel()
{
    switch(action) {
       case 1:
       // First code
       break;

       case 2:
       // Second code
       break;
    }
}

template void kernel<1>();
template void kernel<2>();

Ответ 2

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

Если это имеет большое значение, возможно, стоит переместить условие вне цикла. Если деформация действительно расходятся, подумайте о том, как удалить ветвление: например, вместо

if (i>0) {
    x = 3;
} else {
    x = y;
}

попробовать

x = ((i>0)*3) | ((i<3)*y);