Compiler avec GCC sur Sam440 :Comment optimiser?

15 sujets de 16 à 30 (sur un total de 33)

  • corto

      #158707

      K-L : Pas faux ! ;-)

      Donc au final 0% sur les tâches prévues mais c’est pas grave, la problématique exposée ici est plus qu’intéressante.

      Le 440 supporte bien le prefetch et il y a quelques réglages dans le Core Configuration Register CCR0.

      corto

        #158708

        thellier : Après avoir réfléchi et expérimenté à nouveau, tant bien que mal (malheureusement, j’ai peur que des photos où je suis en train de “réfléchir” circulent sur Internet), sur le MicroAOne, j’obtiens 13 fps au lieu de 10, et je descends à 50% de temps passé dans Wazp3D, avec 240 hits, dont 52 dans la fonction PixelsOut16.

        On essaie sur la Sam440, 6 fps sans option spéciale … et ma version modifiée semble ne pas fonctionner :-(

        corto

          #158709

          Nouvelles du matin :

          – En jouant avec les options, il y a eu une exception DSI en cliquant sur ‘5’. addr2line indique la ligne 647 : zname est un buffer de 5 caractères alors que suivant l’option, on y copie plus de 5 octets.

          – Sur la Sam440 d’Olrick, on a 5 fps avec un écran 32 bits et 6 fps en 16 bits, 7 fps après ma modif, 32 fps avec Warp3D hardware.

          – Sur la Sam460 d’Elwood, on a 7 fps avec un écran 32 bits, 8 fps en 16 bits avec ma version.

          – Sur la Sam440 overclockée de K-L (733 MHz), on a … 3 fps sur un écran 32 bits, même carte graphique qu’Olrick, les 2 ont appliqué le patch sam440_setup.

          Donc je ne comprends pas :

          – l’écart entre les 2 Sam440 !

          – pourquoi ça va 2 fois plus vite sur mon MicroAOne

          thellier

            #158710

            OK vraiment mercis les gars

            tout ce que vous ecrivez est hyper interessant

            Je vais faire ces modifs lundi

            La je suis dans le train et je reponds en bref car depuis 1 telephone

            btw comment je trouve ou sont les hits?

            sinon si vous etes en 24/32bits alors vous utilisez pax pixelsou16

            faut aussi voir que wazp a ete concu pour la jit de winuae =>Instructiond simples et cache important

            ENCORE MERCI

            Alain

            corto

              #158711

              thellier: Je peux t’envoyer ma fonction modifiée si tu veux.

              Sinon, pour les hits, j’utilise Hieronymus … mon profiler :-D mais malheureusement il ne fonctionne toujours pas sur Sam440.

              Ton exemple est hyper intéressant et quelque part, ça valide un peu plus Hieronymus. Après ma modif, j’obtiens :

              Percent | Program

              12 | SYS:Kickstart/newlib.library.kmod

              4 | SYS:Kickstart/timer.device.kmod

              65 | LIBS:Warp3D.library

              3 | SYS:Kickstart/rtg.library

              6 | SYS:Kickstart/kernel

              6 | Cow3D-Amiga-ppc

              1 | SYS:Kickstart/ATIRadeon.chip

              1 | LIBS:Picasso96/emulation.library

              0 | LIBS:bsdsocket.library

              0 | SYS:Kickstart/graphics.library.kmod

              count = 0312, percent = 65, name = LIBS:Warp3D.library

              Offset = 0x000540c8, Count = 0002, Function =

              Offset = 0x000083c8, Count = 0073, Function = PixelsOut16

              Offset = 0x0004bec8, Count = 0026, Function = GetVertex

              Offset = 0x00020a74, Count = 0019, Function = Fill_Tex

              Offset = 0x000467c0, Count = 0017, Function = Edge_Tex

              Offset = 0x00044d5c, Count = 0001, Function = ZbufferCheck

              Offset = 0x00045a28, Count = 0011, Function = DrawPolyPix

              Offset = 0x00044a34, Count = 0040, Function = SOFT3D_ClearZBuffer

              Offset = 0x0000762c, Count = 0034, Function = Ztest_zless_update

              Offset = 0x00045510, Count = 0002, Function = PrintPix

              Offset = 0x000460dc, Count = 0010, Function = Poly_Persp0_Tex

              Offset = 0x00050b9c, Count = 0017, Function = DrawPolyP

              Offset = 0x00007644, Count = 0005, Function = Ztest_zgequal_update

              Offset = 0x00017aa0, Count = 0009, Function = PixelsTex32ToBuffer

              Offset = 0x0000e894, Count = 0001, Function = PrintError

              Offset = 0x0004f3c4, Count = 0009, Function = ClipPoly

              Offset = 0x0001ab08, Count = 0006, Function = SOFT3D_Flush

              Offset = 0x00020fa8, Count = 0010, Function = SetTexStates

              Offset = 0x00052c34, Count = 0003, Function = DrawPrimitive

              Offset = 0x00051c70, Count = 0010, Function = SOFT3D_DrawPrimitive

              Offset = 0x00053f24, Count = 0001, Function = W3D_DrawPoint

              Offset = 0x00008408, Count = 0001, Function = PixelsIn8

              Offset = 0x000127dc, Count = 0002, Function = SelectMipMap

              Offset = 0x00053ebc, Count = 0001, Function = W3D_DrawTriangle

              Offset = 0x0001e9f0, Count = 0001, Function = SetDrawFunctions

              Offset = 0x00004d94, Count = 0001, Function = LibW3D_DrawTriangle

              Donc il semble qu’on passe 2 fois moins de temps dans PixelsOut16 mais que du fait qu’on mette un peu moins de pression sur cette fonction … d’autres fonctions en profitent ! La charge se répartit au sein de l’appli mais elle reste à bloc.

              Une autre fonction à regarder pourrait être ClearZBuffer … A ce propos, si le zbuffer n’utilise pas les float, alors MAXZ défini à 0.99999, converti en USHORT … je pense que ça va écrire des zéros.

              Si dans ClearZBuffer, on peut tout mettre à zéro, alors le PPC peut bénéficier de l’instruction de clear de cache. Je ne sais pas si c’est vraiment conseillé mais bon … (et il faut faire attention, la taille d’une ligne de cache est usuellement 32 octets, mais 64 sur X1000 et 128 sur G5 je crois).

              thellier

                #158712

                Hello

                oui Corto envoie moi tes modifs a mon nom chez free.fr

                Merci

                Non non le zbuffer doit bien etre vide’ a 1.00

                (0.0 est le plan de l ecran et 1.0 le plus loin)

                j utilise 0.99 pour etre tranquille

                Alain

                AmiDARK

                  #158713

                  @Thellier :

                  Il y a aussi une astuce qui permet d’avoir à vider le ZBuffer d’une frame à l’autre … Sur AmigaOS4 cela m’a permis de grandement améliorer le frame Rate de l’AmiDARK Engine :)

                  @ +

                  AmiDARK

                  thellier

                    #158714

                    >une astuce qui permet d’avoir à vider le ZBuffer

                    Et on peut la connaitre ?

                    Alain

                    AmiDARK

                      #158715

                      @Thellier :

                      Salut Alain,

                      En fait tu travailles par quart de buffer.

                      Et tu modifies le test > ou < en conséquence. Voila ma fonction qui gère le schmilblik sous AmiDARK Engine :

                      void UpdateZTrickMode( int ZTrickADD ){

                      glEnable( GL_DEPTH_TEST );

                      glDepthMask( GL_TRUE );

                      // Mode 0 = Aucune optimisation de gestion du ZBuffer.

                      if ( Core.ZTrick == 0 ){

                      if ( ZTrickADD != 0 ){ glClear( GL_DEPTH_BUFFER_BIT ); }

                      glDepthRange( (GLclampd)0.0f, (GLclampd)1.0f );

                      glDepthFunc( GL_LEQUAL );

                      }else{

                      // Mode 1 = Optimisation du ZBuffer par cadrans de 1/4 du buffer total

                      Core.ZFrameID = Core.ZFrameID + ZTrickADD;

                      switch( Core.ZFrameID ){

                      case 1:

                      glDepthRange( (GLclampd)0.5, (GLclampd)0.75 );

                      glDepthFunc( GL_LEQUAL ); // Default mode less or equal

                      break;

                      case 2:

                      glDepthRange( (GLclampd)0.25, (GLclampd)0.5 );

                      glDepthFunc( GL_LEQUAL ); // Default mode less or equal

                      break;

                      case 3:

                      glDepthRange( (GLclampd)0.0, (GLclampd)0.25 );

                      glDepthFunc( GL_LEQUAL ); // Default mode less or equal

                      break;

                      case 4:

                      glDepthRange( (GLclampd)0.5, (GLclampd)0.25 );

                      glDepthFunc( GL_GEQUAL );

                      break;

                      case 5:

                      glDepthRange( (GLclampd)0.75, (GLclampd)0.5 );

                      glDepthFunc( GL_GEQUAL );

                      break;

                      case 6:

                      glDepthRange( (GLclampd)1.0, (GLclampd)0.75 );

                      glDepthFunc( GL_GEQUAL );

                      Core.ZFrameID = 0;

                      break;

                      case 7:

                      glClear( GL_DEPTH_BUFFER_BIT );

                      glDepthFunc( GL_GEQUAL );

                      glDepthRange( (GLclampd)1.0, (GLclampd)0.75 );

                      Core.ZFrameID = 0;

                      default:

                      break;

                      }

                      }

                      }

                      Cela permet d’utiliser le ZBuffer sans l’effacer et sans avoir aucun problème.

                      Si tu as besoin de plus d’explications sur le principe, n’hésite pas à demander ;)

                      Si tu as besoin de plus de précisions, tu peux travailler en 1/2 de buffer total au lieu de 1/4 ;)

                      @ +

                      AmiDARK

                      thellier

                        #158716

                        Hello

                        C pas bête du tout : Merci

                        je vois l’idée tu exploite un quart de la profondeur du zbuffer

                        à chaque frame et toutes les 4 frames tu vide tout le zbuffer

                        Par contre que je capte pas c’est “Pourquoi y a 7 cases ?”

                        moi j’aurai fait 4 cases

                        0: de 0.00 à 0.25 + glClear( GL_DEPTH_BUFFER_BIT );

                        1: de 0.25 à 0.50

                        2: de 0.50 à 0.75

                        3: de 0.75 à 1.00

                        A la limite on peut faire le truc en 6 lignes :

                        glEnable( GL_DEPTH_TEST );

                        glDepthMask( GL_TRUE );

                        glDepthFunc( GL_GEQUAL );

                        n= Core.ZFrameID % 4;

                        if(n==0) glClear( GL_DEPTH_BUFFER_BIT );

                        glDepthRange(n*0.25,(n+1)*0.25 );

                        Alain

                        AmiDARK

                          #158717

                          En fait, c’est pire, je ne le vide jamais…

                          Je le vide à l’initialisation pour être sûr que tout soit à 0

                          puis :

                          7 = Initialisation du ZBuffer.

                          La commande système qui initialise l’activation du ZTrick active le ZFrameID = 6 (résultat, au 1er appel il passe à 7 et initialise le ZBuffer en le vidant). Puis ça le mets à 0 (compteur qui sera automatiquement à 1 à la prochaine boucle via Core.ZFrameID = Core.ZFrameID + ZTrickAdd )

                          Puis ça boucle entre 1 à 6:

                          1. de 0.50 à 0.75 ( 0.50 = proche, 0.75 = loin ) GL_LEQUAL : Less or Equal

                          2. de 0.25 à 0.50 ( 0.25 = proche, 0.50 = loin ) GL_LEQUAL : Less or Equal

                          3. de 0.00 à 0.25 ( 0.00 = proche, 0.25 = loin ) GL_LEQUAL : Less or Equal

                          4. de 0.50 à 0.25 ( 0.50 = proche, 0.25 = loin ) GL_GEQUAL : Greater or Equal

                          5. de 0.75 à 0.50 ( 0.75 = proche, 0.50 = loin ) GL_GEQUAL : greater or Equal

                          6. de 1.00 à 0.75 ( 1.00 = proche, 0.75 = loin ) GL_GEQUAL : Greater or Equal + Remise à 0 du pointeur de ZFrameID (compteur qui sera automatiquement à 1 à la prochaine boucle via Core.ZFrameID = Core.ZFrameID + ZTrickAdd )

                          Donc, j’utilise le ZBuffer dans les 2 sens … Résultat, aucun besoin de le vider. Les valeurs de la gestion précédente étant toujours en dehors du nouveau RANGE et considérée comme distances + loin que la maxi de la nouvelle frame … Aucun besoin de le vider :p

                          Voila :)

                          Maintenant, cette idée ne vient pas de moi … je crois que c’est Corto qui m’en avait parlé (enfin, du principe) et on avait vu ensemble pour optimiser cela :p

                          @ +

                          AmiDARK

                          corto

                            #158718

                            thellier : Un aperçu de la désormais fameuse vache tournante le week-end dernier ;-)

                            AmiDARK

                              #158719

                              @Corto :

                              Quel était l’objectif à atteindre derrière cette 3DCow ?

                              thellier

                                #158720

                                @Corto

                                trop fort

                                >Quel était l’objectif à atteindre derrière cette 3DCow ?

                                http://thellier.free.fr/Cow3D-stars.png

                                1) faire un source C de démonstration de comment programmer Warp3D sans dépendances à MiniGL ou StormMesa ni Glut (en pur Warp3d.library + graphics.library)

                                2) Fournir un programme de test des fonctionnalités de Warp3D qui soit mieux écrit/plus beau/plus complet que le classique WarpTest

                                3) Servir éventuellement de benchmark d’une machine à l’autre: malheureusement ceci est pas trop le cas car sur Os4(=Warp3D v5) le W3D_DrawElements() (=fonction rapide) se refuse à marcher (=bug) comme sur les autres OS (Warp3d v4) donc j’utilise sur os4 le lent W3D_DrawTriangle()

                                En bref sur Os4 mon Cow3D est plus lent que ce qu’il devrait être…

                                Bref ça peut servir à

                                comparer des machines Os4 entre elles

                                OU

                                comparer des machines Os3 ,WinUAE, Aros entre elles

                                A l’occasion il faudra que je corrige ça….

                                Alain Thellier

                                AmiDARK

                                  #158721

                                  @Thellier : Ok.

                                  Interessant effectivement.

                                  Sinon, j’ai du mal à voir sur les photos et avec le shot que tu as mis en lien.

                                  La vache est un objet 3D ou une texture plaquée (genre un objet 3D plain) ?

                                  PS : Ca m’intéresserait de voir le code source si il est prévu qu’il soit public ;)

                                  @ +

                                  AmiDARK

                                15 sujets de 16 à 30 (sur un total de 33)

                                • Vous devez être connecté pour répondre à ce sujet.

                                Forums AmigaOS, MorphOS et AROS Développement Compiler avec GCC sur Sam440 :Comment optimiser?

                                Amiga Impact