[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 donamigadonamiga, le il y a 1 mois.
  • Créateur
    Sujet
  • #102244
    Arnaud.68000Arnaud.68000
    • Level 2
    • Messages : 49

    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 !

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 4
    • Messages : 146

    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.68000Arnaud.68000
    • Level 2
    • Messages : 49

    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
    donamigadonamiga
    • Level 5
    • Messages : 238

    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 :

     

    the b(l)itter end - A500 +512 1.2/A500 +512 1.3 marche p'us/A1200 3.0 4mb fast/A3000 8 mb fast 2.04+1.3/Gotek externe

    #102264
    lexomillexomil
    • Level 3
    • Messages : 77

    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 4
    • Messages : 146

    @ 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.68000Arnaud.68000
    • Level 2
    • Messages : 49

    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
    lexomillexomil
    • Level 3
    • Messages : 77

    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
    donamigadonamiga
    • Level 5
    • Messages : 238

    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

     

    the b(l)itter end - A500 +512 1.2/A500 +512 1.3 marche p'us/A1200 3.0 4mb fast/A3000 8 mb fast 2.04+1.3/Gotek externe

    #102430
    Arnaud.68000Arnaud.68000
    • Level 2
    • Messages : 49

    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
    donamigadonamiga
    • Level 5
    • Messages : 238

    ;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

     

    the b(l)itter end - A500 +512 1.2/A500 +512 1.3 marche p'us/A1200 3.0 4mb fast/A3000 8 mb fast 2.04+1.3/Gotek externe

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