[ASM 68000] Mesurer les cycles d’un code

Forum Amiga Coding [ASM 68000] Mesurer les cycles d’un code

  • Ce sujet contient 10 réponses, 4 participants et a été mis à jour pour la dernière fois par donamiga, le il y a 3 années et 5 mois.
  • Créateur
    Sujet
  • #102244
    Arnaud.68K
    • Level 3
    • Messages : 69

    Bonjour,

    L’un de vous sait il comment mesurer le nombre de cycles d’un programme en assembleur (68000) sur Amiga.

    Après quelques recherches, j’ai pas trouvé de registre qui va bien, la mesure de la position du balayage écran étant une solution mais si on pouvait compter les cycles ce serait top.

    Mon but est d’optimiser du code et d’avoir une mesure factuelle.

    Merci pour votre aide

     

    A500 + 512k, adepte du SM attention avec un A devant !

Affichage de 10 réponses de 1 à 10 (sur un total de 10)

Partager sur vos réseaux sociaux préférés :
Facebooktwitterredditpinterestlinkedintumblrmail

  • Auteur
    Réponses
  • #102245
    slack
    • Level 7
    • Messages : 457

      Bonjour Arnaud.68000,

      Que veux-tu dire par mesurer le nombre de cycles d’un programme ?

      Dans la documentation motorola, il y a le nombre de cycles d’horloge que prend chaque instruction.

       



      #102246
      Arnaud.68K
      • Level 3
      • Messages : 69

        Merci Slack,

        Ce que j’entends par mesurer le nombre de cycles (horloge) c’est si j’exécute un code du type :

        moveq #0,d1

        move.w #25,d0

        _Boucle:

        Add.l #1,d1

        dbf d0,_Boucle

        Il va consommer un certains nombre de cycles horloges.

        Si je remplaçant add.l par addq, il va peut être consommer moins de cycles.

         

        Me référer à une table de correspondance des cycles utilisés par instruction peut être fastidieux surtout si le code à des boucle et des tests.

        Ce qui serait top, ce serait d’avoir un truc du type :

        t1=timer

        exécution du code

        t2=timer-t1

        Pour cela je sais pas si il existe un registre sur l’A500 qui s’incrémente en fonction des cycles d’horloge ( ou une technique similaire)

         

         

         

        A500 + 512k, adepte du SM attention avec un A devant !

        #102254
        donamiga
        • Level 5
        • Messages : 249

          timer CIA (B ou TOD)
          voir code de ross :

          http://eab.abime.net/showpost.php?p=1199574

          https://eab.abime.net/showthread.php?t=99238

          sujet:

          http://eab.abime.net/showthread.php?t=88383

          peut etre que ça peut aider

          j’allais oublier le tuto de Jel sur les CIA :

           

          #102264
          lexomil
          • Level 3
          • Messages : 80

            Salut !

            si ton code tient dans une VBL le plus simple reste quand même de changer la couleur du fond au début et à la fin de ta fonction. ça te donnera pas le nombre de cycles écoulés (pour ça rien de mieux que de le faire à la main), mais tu verra rapidement si un changement te fais gagner ou perdre du temps.

            #102277
            slack
            • Level 7
            • Messages : 457

              @ Arnaud.68000,

              Voici quelques informations et demandes de renseignements pour mieux t’aider.

               

              Les tables fournies par Motorola pour le processeur 68000 permettent de compter facilement les cycles utilisés par du code aussi simple que :

              moveq #0,d1

              move.w #25,d0

              _Boucle:

              Add.l #1,d1

              dbf d0,_Boucle

              Les boucles ne compliquent pas le calcul.

              Par contre, je ne connais pas de tables pour les processeurs à partir du 68020.

               

               

              Que veux-tu faire ? Coder une boucle d’attente ? Optimiser du code ?

               

               

              As-tu besoin d’une mesure précise du temps écoulé entre les deux lectures du timer ?

              Pour une mesure grossière, tu peux laisser le multitâche et les interruptions. Sur un système non chargé, tu répète les mesures et tu prends la plus courte.

              Pour une mesure précise, ton code ne doit pas être interrompu entre les deux lectures du timer. Je pense qu’il faut interdire les interruptions avant de la première lecture et les autoriser après la seconde. Attention, tu risques de perturber le fonctionnement du système d’exploitation si tu coupes les interruptions pendant une durée trop longue.

               

              Tu peux regarder les 2 articles suivants :

              http://obligement.free.fr/articles/assembleur_ressources.php

              http://obligement.free.fr/articles/c_cia.php

              #102345
              Arnaud.68K
              • Level 3
              • Messages : 69

                Bonjour,

                Merci pour vos réponses

                @DonAmiga & Slack : pas mal les liens je vais prendre le temps de regarder tout ça

                @Lexomil : oui j’ai déjà une routine pour visualiser le cycle VBL (quand ça rentre dedans), mais des fois des changements minimes ne se voient pas facilement avec le VBL

                @Slack : oui je souhaite chercher une mesure précise de mon code pour voir les effets de mes optimisations (l’idée est aussi la démarche intellectuelle) et parfois on parle de quelques cycles localement ici et là ou parfois de code assez long.

                Je me souviens d’avoir fait (il y a 25 ans)  un code pour pivoter  3 fois de 90° des lettres 32×32 ayant différents angles 0°, 10 ,20,30,40,50,60,70,80°, en vu de faire un scroll rotatif 360°. Mon code prenait 3 à 4 secondes en pre-traitement. Je pense que ce code (si je le retrouve) est largement optimisable.  C’est pour cela qu’une mesure serait la bienvenue.

                Sinon il y a bien easy68k, un assembleur 68000 sur PC, qui donne le nombre de cycles utilisés après execution mais il ne tient pas compte de l’env Amiga.

                 

                Je vais regarder vos suggestions, merci encore

                A500 + 512k, adepte du SM attention avec un A devant !

                #102351
                lexomil
                • Level 3
                • Messages : 80

                  Ha ok, c’est vraiment pour mesurer des routines assez « lourdes », dans ce cas je penses que le plus adapté c’est en utilisant les timers du système.

                  Jette un oeil du coté de la lowlevel.library (ROM 3.1) et de la méthode ElapsedTime ça pourrait te suffire, la granularité est de l’ordre de la microseconde donc à même d’évaluer une différence entre deux implémentations de ta routine.

                  #102354
                  donamiga
                  • Level 5
                  • Messages : 249

                    bin oui, c’est pour ça que j’ai mis le lien de la routine de ross: http://eab.abime.net/showpost.php?p=1199574

                     

                    #102430
                    Arnaud.68K
                    • Level 3
                    • Messages : 69

                      Voici en synthèse les 2 codes issus de vos suggestions, ajustés et complémentaire (pour A500)

                      L’un mesure le nombre de cycles pour des routines courtes inférieures au temps du faisceau horizontal.

                      L’autre mesure des routines plus conséquentes en ms (convient moins à un nombre d’instructions faibles)

                      Code pour mesurer des cycles :

                      **********************************************************
                      ;Code pour mesurer les cycles d’un code inferieur au temps de trace d’une ligne
                      ;Calibre pour A500
                      ;
                      ;Resultat dans D0 = nombre de cycles, D1=Start, D2=Stop
                      ;
                      ;Sources :
                      ;http://eab.abime.net/showpost.php?p=1199574
                      ;http://eab.abime.net/showthread.php?t=88383

                      section code,code

                      DMACONR=$002
                      VHPOSR=$006
                      INTENA=$09A
                      INTENAR=$01C
                      INTREQ=$09C
                      INTREQR=$01E
                      DMACON=$096

                      ;———- Macros ———-

                      ;Attendre le Blitter
                      ;Quand la seconde opérande est une adresse, BTST ne permet de tester que les bits 7-0 de l’octet pointé,
                      ;mais traitant la première opérande comme le numéro du bit modulo 8,
                      ;BTST #14,DMACONR(a5) revient à tester le bit 14%8=6 de l’octet de poids fort de DMACONR,
                      ;ce qui correspond bien à BBUSY…

                       

                      WAITBLIT: MACRO
                      _waitBlitter0\@
                      btst #14,DMACONR(a5)
                      bne _waitBlitter0\@
                      _waitBlitter1\@
                      btst #14,DMACONR(a5)
                      bne _waitBlitter1\@
                      ENDM

                      start:
                      clr.l d0
                      lea $DFF000,a5

                      move.w #$4000,INTENA(a5) ;INTENA INTEN off
                      move.w #$0200,DMACON(A5) ;DMACON DMAEN off

                      WAITBLIT

                      move.l #$DFF006,a0 ;VHPOSR
                      WaitRaster:
                      cmp.b #$00,(a0) ;test if Hpos=0
                      bne WaitRaster

                      move.w (a0),d1 ;start_value

                      ;— Code à tester —
                      ;nop ;unknown_cycles to count
                      move.l #15,D5
                      ;— FIN CODE —

                      move.w (a0),d2 ;end_value (we know this takes $00000004)
                      move.w d2,d0 ;end_value to d2
                      sub.w d1,d0 ;end_value – start value
                      sub.w #$4,d0 ;d2 – $00000004
                      add d0,d0 ;d2 x 2 = unknown_cycles

                      Fin:
                      move.w #$8200,DMACON(A5) ;DMACON DMAEN ON
                      move.w #$C000,INTENA(a5) ;INTENA INTEN ON
                      rts

                      **********************************************************

                       

                      Code pour mesurer un temps en ms

                      **********************************************************
                      ;Code pour mesurer des codes d’execution assez longs en ms
                      ;car le temps de la sub de VPOS Stop est inclus
                      ;Calibre pour A500
                      ;
                      ;resultat dans D0 = ms
                      ;
                      ;Sources modifie :
                      ;code speed tester by ross for EAB members
                      ;http://eab.abime.net/showpost.php?p=1199574
                      ;
                      PAL = 15625
                      NTSC = 15734
                      ConfigEcran=PAL

                      CIAA =$BFE001
                      CIAB =$BFD000
                      PRA =$000 ;/DTR /RTS /CD /CTS /DSR SEL POUT BUSY
                      prb =$100 ; /MTR /SEL3 /SEL2 /SEL1 /SEL0 /SIDE DIR /STEP
                      DDRA =$200 ;Direction for Port A (BFD000);1 = output (set to 0xFF)
                      DDRB =$300 ;Direction for Port B (BFD100);1 = output (set to 0xFF)
                      TALO =$400 ;CIAB timer A low byte (.715909 Mhz NTSC; .709379 Mhz PAL)
                      TAHI =$500 ;CIAB timer A high byte
                      TBLO =$600 ;CIAB timer B low byte (.715909 Mhz NTSC; .709379 Mhz PAL)
                      TBHI =$700 ;CIAB timer B high byte
                      TODLO =$800 ;Horizontal sync event counter bits 7-0
                      TODMID =$900 ;Horizontal sync event counter bits 15-8
                      TODHI =$A00 ;Horizontal sync event counter bits 23-16
                      SDR =$C00 ;CIAB serial data register (unused)
                      ICR =$D00 ;CIAB interrupt control register
                      CRA =$E00 ;CIAB Control register A
                      CRB =$F00 ;CIAB Control register B

                      section code,code

                      start:
                      lea $DFF000,a5
                      lea CIAB,a4

                      move.w #$4000,$9A(a5) ;INTENA INTEN off
                      move.w #$0200,$96(A5) ;DMACON DMAEN off
                      BltWait:
                      move.w 2-$9a(a5),d0 ; blitter wait
                      add.w d0,d0
                      bmi.b BltWait

                      ;if you need to init/move/setup packed data
                      jsr init

                      bsr.b CIAtoD ; start time
                      move.l d0,d2

                      jsr Code ; GO!

                      bsr.b CIAtoD ; end time

                      sub.l d2,d0 ; elapsed

                      ;15625=PAL 15734=NTSC
                      divu.w #ConfigEcran*256/1000,d0 ; d0=ms (pal_hfreq*scale_down/granularity)
                      bvs.b OverFlow ; overflow?, something over specs..
                      and.l #$FFFF,d0
                      bra fin

                      OverFlow:
                      move.l #$EEEEEEEE,D0 ;erreur
                      Fin:
                      move.w #$8200,$96(A5) ;DMACON DMAEN ON
                      move.w #$C000,$9A(a5) ;INTENA INTEN ON

                      rts

                      CIAtoD:
                      move.b TODHI(a4),d0 ;$200(a4),d0
                      swap d0
                      move.b TODMID(a4),d0 ;$100(a4),d0
                      lsl.w #8,d0
                      move.b TODLO(a4),d0
                      lsl.l #8,d0 ; scale up (counter wrap proof)
                      rts

                      Init: ; insert your init code here (not timed)
                      rts

                      Code: ; insert your code here (a500 is the target)
                      move.l #200000,d1
                      .loop
                      move.w d1,$dff180
                      subq.l #1,d1
                      bne.b .loop
                      rts
                      **********************************************************

                      Pour aller plus loin

                      A l’occasion je vais voir si on peut faire des 2 codes un code générique qui mesure à la fois les cycles et le temps d’exécution quelque soit la taille de la routine à évaluer.

                      Mais si quelqu’un veut se pencher avec moi sur le sujet j’ai rien contre ;-)

                      Encore merci pour votre aide.

                       

                      A500 + 512k, adepte du SM attention avec un A devant !

                      #102436
                      donamiga
                      • Level 5
                      • Messages : 249

                        ;BTST #14,DMACONR(a5) revient à tester le bit 14%8=6 de l’octet de poids fort de DMACONR,
                        ;ce qui correspond bien à BBUSY…

                        d’ailleurs on ecrit : btst #6,DMACONR(a5)

                        déjà pas besoins de 2 sources differents pour les 2 methodes, mettre les 2 routs dans 1 source avec le code à tester

                        utiliser des reg differents pour calcul et sauvegarde des resultats de chaque test

                        ajouter pour sauver ces regs avant l’execution du code:
                        Code:
                        movem.l d0-d7/a0-a6,-(sp) ; tous ou registres à sauver seulement

                        movem.l (sp)+,d0-d7/a0-a6
                        rts

                         

                      Partager sur vos réseaux sociaux préférés :
                      Facebooktwitterredditpinterestlinkedintumblrmail
                      Affichage de 10 réponses de 1 à 10 (sur un total de 10)
                      • Vous devez être connecté pour répondre à ce sujet.