- 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éateurSujet
-
28 octobre 2020 à 17 h 02 min #102244Arnaud.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 !
-
CréateurSujet
-
AuteurRéponses
-
28 octobre 2020 à 17 h 09 min #102245slack
- 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.
28 octobre 2020 à 17 h 36 min #102246Arnaud.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 !
28 octobre 2020 à 18 h 46 min #102254donamiga- 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 :
28 octobre 2020 à 20 h 00 min #102264lexomil- 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.
28 octobre 2020 à 23 h 15 min #102277slack- 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
29 octobre 2020 à 14 h 01 min #102345Arnaud.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 !
29 octobre 2020 à 15 h 45 min #102351lexomil- 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.
29 octobre 2020 à 15 h 52 min #102354donamiga- 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
30 octobre 2020 à 15 h 59 min #102430Arnaud.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=88383section 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\@
ENDMstart:
clr.l d0
lea $DFF000,a5move.w #$4000,INTENA(a5) ;INTENA INTEN off
move.w #$0200,DMACON(A5) ;DMACON DMAEN offWAITBLIT
move.l #$DFF006,a0 ;VHPOSR
WaitRaster:
cmp.b #$00,(a0) ;test if Hpos=0
bne WaitRastermove.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_cyclesFin:
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=PALCIAA =$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 Bsection code,code
start:
lea $DFF000,a5
lea CIAB,a4move.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 initbsr.b CIAtoD ; start time
move.l d0,d2jsr 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 finOverFlow:
move.l #$EEEEEEEE,D0 ;erreur
Fin:
move.w #$8200,$96(A5) ;DMACON DMAEN ON
move.w #$C000,$9A(a5) ;INTENA INTEN ONrts
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)
rtsInit: ; insert your init code here (not timed)
rtsCode: ; 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 !
30 octobre 2020 à 17 h 46 min #102436donamiga- 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 -
AuteurRéponses
- Vous devez être connecté pour répondre à ce sujet.