IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

quake 3 isqrt en C++ ?


Sujet :

C++

  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut quake 3 isqrt en C++ ?
    Bonjour, c'est encore moi avec mes problèmes tordus Je suis en pleine période je martyrise mon pauvre gcc.

    Au menu du jour, la fonction qui calcule l'inverse d'une racine carré a la sauce quake 3. L'original est en C :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        long i;
        float x2, y;
        const float threehalfs = 1.5F;
     
        x2 = number * 0.5F;
        y  = number;
        i  = * ( long * ) &y;  // evil floating point bit level hacking
        i  = 0x5f3759df - ( i >> 1 ); // what the fuck?
        y  = * ( float * ) &i;
        y  = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
        // y  = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
        return y;
    Voila ce que donne l'original.

    Mais ici on est en C++ et ces cast mode C ne font pas propres ! j'ai donc essayé différentes chose, mais impossible de faire gober ca a mon gcc sans qu'il ne se fache :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i = reinterpret_cast<long>(y);   // evil floating point bit level hacking
    Donne une erreur : invalide cas from type float to type long int.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i = *reinterpret_cast<long*>(&y);   // evil floating point bit level hacking
    Donne quand a lui attention : déréférencement du pointeur type-punned brisera les strictes d'aliases . Il est possible de compiler quand même mais le code ne fonctionne pas.

    Google ne m'aide pas beaucoups sur ce coup la. je crois qu'il ne m'aime aps ces temps-ci . . .

    A noter que sans l'option de compilation -O3, le second code marche.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    J'ai trouvé la solution en fouinant sur cette page : http://gcc.gnu.org/onlinedocs/gcc/Op...timize-Options

    Il faut utiliser une union du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    union converter {
       long i;
       float y;
    };

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Les unions ça fonctionne ne pratique mais pas en théorie, donc à éviter. Ceci-dit je pense qu'il n'y a que ça qui fonctionne avec les options d'optimisations poussées.

    A part ça, les hacks de ce genre c'est bien mais c'est plus trop utile. Si tu finis ton jeu et lances un profiler, tu verras que ce n'est pas là que les pertes de performances se trouvent. Alors ne te prends pas trop la tête avec ce genre de code.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Salut.
    Attention normalement, le chiffre magique ne fonctionne que sur 32 bits et
    long et float doit être de même taille.

    Si ca t'intéresse, voici un benchmark
    ktd.club.fr/programmation/fichiers/FastMath.pdf

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    A part ça, les hacks de ce genre c'est bien mais c'est plus trop utile. Si tu finis ton jeu et lances un profiler, tu verras que ce n'est pas là que les pertes de performances se trouvent. Alors ne te prends pas trop la tête avec ce genre de code.
    Je sais bien, mais je suis dans une période ou je teste un peu tout et n'importe quoi pour voir comment ça réagit. Je ne compte pas recoder intégralement la lib mathématique

  6. #6
    NairodDorian
    Invité(e)
    Par défaut
    ça c'est le genre de code C totalement inutile et illisible mais optimisé.
    deux instructions asm et c'est réglé avec des perfs supérieur.

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Je ne penses pas que carmack ou tarolli puissent être traités de branlo faisant du mauvais code

  8. #8
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par deadalnix Voir le message
    Je ne penses pas que carmack ou tarolli puissent être traités de branlo faisant du mauvais code
    Bah, disons que ça s'explique mathématiquement : http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf

  9. #9
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Je crois qu'il ne faut pas confondre code hyper optimisé (comme Carmack le faisait encore il y a quelques années) et code propre...

    Ce code est *sale*... Pourquoi ? parceque le programmeur lambda qui va arriver dans ce code, avec comme nécessité, par exemple, de le transformer pour une autre norme de float(s) va s'arracher les cheveux, et commencer par perdre 2j pour comprendre comment ça marche et pourquoi ça marchote...
    2j pour 6 lignes de code, c'est beaucoup trop à mon avis....

    Le rsqrt hack ci-dessus existe pour plein de fonctions (et d'ailleurs, si je me souviens bien, n'avait pas été "trouvé" par Carmack mais par un mec de Nvidia, mais je peux me gourrer).

    Toutefois, il tend à être *completement* inutile aujourd'hui... Quake3 c'était quand même il y a 10 ans !
    D'abord parcequ'il existe une instruction assez rapide dans le proc pour le faire, et ensuite, parcequ'en général, on a besoin de "normaliser" que très tard, et quand c'est sur une carte graphique, la fonction "nrm" est pratiquement gratuite... (sans compter qu'elle n'utilise même pas le CPU).

    Tant qu'on est à faire de l'illisible... pourquoi pas...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    inline float RsqrtSSE(float f)
    {
        __asm
        {
            rsqrtss xmm0, f
            movss f, xmm0
        }
        return f;
    }
    Et... je suis pas sur que le Newton gagne !
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Citation Envoyé par deadalnix Voir le message
    ... tarolli ...
    Tu notera que je n'ai pas utilise le mot propre sou sale mais bon ou mauvais.

    Maintenant il est clair qu'utilise les fonctions intégrées dans nos puces en hard est une meilleure idée.

  11. #11
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Mais moi je dis, que le code est non seulement SALE, mais en plus MAUVAIS
    Il existe une constante qui marche bien mieux que celle que tu montres.... (je te laisses le soin de la calculer, c'est assez facile, et ca permet de comprendre comment tout ça fonctionne).

    J'en profite pour ressortir ma "vieille" lib mathématique, genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    /** Tells the compiler to consider "f" as a signed integer */
    #define	RW_ASINT32(f)			(*((SInt32_t*)&f))
    /** Tells the compiler to consider "i" as a floating-pointer number */
    #define	RW_ASFLOAT32(i)			(*((Float32_t*)&i))
     
     
    /** \internal bias value for fast integer32/float32 conversion */
    #define	RW_NBIASF			12582912.0f
    /** \internal bias value for fast integer32/float32 conversion */
    #define	RW_NBIASI			1262485504
    /** \internal bias value for fast integer32/float32 conversion */
    #define	RW_PBIASF			8388608.0f
    /** \internal bias value for fast integer32/float32 conversion */
    #define	RW_PBIASI			1258291200
     
    /** \brief      Tests if v is positive. Only works with 32 bits types. */
    #define	IS_POSITIVE(v) ((RW_ASINT32(v) & 0x80000000) == 0)
    /** \brief      Tests if v is negative. Only works with 32 bits types. */
    #define	IS_NEGATIVE(v) ((RW_ASINT32(v) & 0x80000000) != 0)
     
     
    /** \brief Fast conversion from Float_t to SInt32_t. */
    RW_INLINE SInt32_t FloatToSInt32(Float_t f)
    {
    	if (IS_NEGATIVE(f)) {
    		f += RW_NBIASF;
    		RW_ASINT32(f) -= RW_NBIASI;
    	} else {
    		f += RW_PBIASF;
    		RW_ASINT32(f) -= RW_PBIASI;
    	}
    	return RW_ASINT32(f);
    }
    20 fois plus rapide que le proc ! (faut dire que ca stall pas l'ALU et le FPU en même temps).
    Mais bon... vu que ca ne sert plus à rien de transformer un flottant en entier....
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

Discussions similaires

  1. Support des shaders quake III : Irrlicht, Ogre ou aucun ?
    Par inertia dans le forum Moteurs 3D
    Réponses: 2
    Dernier message: 27/02/2006, 20h00
  2. Model de quake 3
    Par Wyatt dans le forum OpenGL
    Réponses: 3
    Dernier message: 30/11/2005, 10h00
  3. Code source Quake 3
    Par SteelBox dans le forum OpenGL
    Réponses: 20
    Dernier message: 29/08/2005, 10h40
  4. Quake 3: couldn't open openGL
    Par poxvx dans le forum OpenGL
    Réponses: 2
    Dernier message: 25/06/2003, 17h53
  5. bsp Quake 2
    Par Argh! dans le forum OpenGL
    Réponses: 3
    Dernier message: 12/09/2002, 17h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo