c++ Devrais-je unifier deux noyaux similaires avec une instruction 'if', risquant ainsi une perte de performance?



cuda libraries (2)

J'ai 2 fonctions de noyau très similaires, dans le sens où le code est presque le même, mais avec une légère différence. Actuellement j'ai 2 options:

  • Ecrire 2 méthodes différentes (mais très similaires)
  • Ecrivez un seul noyau et placez les blocs de code qui diffèrent dans une instruction if / else

Combien une instruction if affecte-t-elle les performances de mon algorithme?
Je sais qu'il n'y a pas de branchement, puisque tous les threads dans tous les blocs entreront dans le si, ou l'autre.
Est-ce qu'une seule instruction if diminuera mes performances si la fonction du noyau est appelée plusieurs fois?

https://ffff65535.com


Cela va légèrement diminuer vos performances, surtout si c'est dans une boucle interne, puisque vous gaspillez une fente d'émission d'instructions de temps en temps, mais ce n'est pas autant que si une chaîne était divergente.

Si c'est un gros problème, il peut être utile de déplacer la condition en dehors de la boucle, cependant. Si la distorsion est vraiment divergente, pensez à la façon de supprimer la ramification: par exemple, au lieu de

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

essayer

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

Vous avez une troisième alternative, qui consiste à utiliser la modélisation C ++ et à rendre la variable utilisée dans l'instruction if / switch un paramètre de modèle. Instancier chaque version du noyau dont vous avez besoin, et ensuite vous avez plusieurs noyaux qui font des choses différentes sans divergence de branche ou sans évaluation conditionnelle, car le compilateur optimisera le code mort et le branchement avec lui.

Peut-être quelque chose comme ça:

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>();




gpgpu