GLSL IF vitesse vs multiplicateur

Je sais que cela a été demandé en général mais la réponse est toujours “dépend”, donc je crée une question concrète dans l’espoir d’obtenir une réponse concrète.

Je connais le mal des IF sur GLSL, elles peuvent être très chères, même exécuter tout le code dans certains matériels.

Donc, j’ai un fragment shader à partir d’un exemple (une double carte d’ombre paraboloïde) qui utilise si pour déterminer quelle carte utiliser et calculer la profondeur, mais je sais qu’il est très facile de les remplacer par un multiplicateur. un échantillonnage de texture à l’intérieur du fragment shader, que serait-il plus rapide d’utiliser un if ou d’utiliser un multiplicateur pour filtrer les données inutilisées?

Voici les codes proposés:

SI version:

//Alpha is a variable computed on the fly, cannot be replaced float depth = 0; float mydepth = 0; if(alpha >= 0.5f) { depth = texture2D(ShadowFrontS, P0.xy).x; mydepth = P0.z; } else { depth = texture2D(ShadowBackS, P1.xy).x; mydepth = P1.z; } 

Version du filtre:

 float mlt = ceiling(alpha - 0.5f); float depth = 0; float mydepth = 0; depth = texture2D(ShadowFrontS, P0.xy).x * mlt; mydepth = P0.z * mlt; mlt = 1.0f - mlt; depth = depth + (texture2D(ShadowFrontS, P1.xy).x * mlt); mydepth = P1.z * mlt; 

PD: je cible les périphériques de bureau et mobiles, donc les performances sur le matériel bas de gamme sont indispensables.

Le twigment n’est pas “diabolique” en soi sur les architectures massivement SIMD. Si tous les threads d’un “tas” (NVidia les appelle Warps) suivent le même chemin de code, c’est-à-dire prendre toutes les mêmes twigs, tout va bien.

Ce n’est que si une twig est en partie prise (dans ce groupe) et pour l’autre partie que les deux twigs doivent être exécutées et plus tard les calculs et les extractions de données ignorés qui ne sont pas pertinents pour le thread en cours.

Maintenant, dans votre cas, cela nécessite un profilage minutieux pour voir, quelle variante profite davantage à votre GPU. Mais mon instinct me dit que c’est en fait la version branchée. Pourquoi? Parce que: Habituellement, la valeur par laquelle vous décidez sur une twig dépend de la position de l’espace écran et souvent de grandes zones contiguës de fragments partagent le même chemin de code et la même twig; les pénalités de performance ne se produisent donc que pour les “grappes”, qui couvrent une région limitrophe. Ces paquets ne font généralement que quelques pixels² (8 × 8 ou 16 × 16).

Le shader que vous avez là n’est pas limité au GPU (limité par les capacités de calcul du GPU), mais la bande passante mémoire est limitée, c’est-à-dire par le débit que la liaison mémoire du GPU offre; c’est à cause des opérations d’extraction de texture2D. Et dans ce cas, la réduction du nombre réel de récupérations et par conséquent de la bande passante mémoire requirejse bénéficiera probablement davantage à votre programme que la réduction du nombre de calculs.

La variante mix-multiplex sans twig de votre shader ira toujours chercher les deux textures, la twig ne le faisant que dans les régions limitrophes. Donc, à partir de cette heuristique, je suppose que votre variante de twigment est en fait le meilleur choix.

Mais pour être sûr que vous devez le profiler .