Logicielsmoto.com http://www.logicielsmoto.com/phpBB/ |
|
atan2 http://www.logicielsmoto.com/phpBB/viewtopic.php?f=3&t=673 |
Page 2 sur 2 |
Auteur: | Bentoc [ 21 Mai 2022, 23:53 ] |
Sujet du message: | Re: atan2 |
Ah ouais bien ! bon il y a un coup d'entrée, mais après c'est mega rapide effectivement. Je n'ai pas pensé au "arsd" "splitté" avec les octets non contigus ... la puissance du 8bit ;-) Si je délégue la partie d’init au code appellant j’évite d’avoir a passer par x et y, ça peut le faire !! |
Auteur: | Bentoc [ 22 Mai 2022, 14:51 ] |
Sujet du message: | Re: atan2 |
En relisant le code d'origine on voit que les cas x=0 et y=0 ne sont pas gérés juste les - et +. Dans mon cas il m'importe d'avoir des valeurs exactes quand x et/ou y sont à 0, donc obligé d'ajouter du code spécifique ... Au final sur 265 tests (cercle de 256 valeurs, et 9 cas particuliers) on obtient 160 cycles en moyenne (sans le jsr). Si qq passe par ici un jour et a mieux, n'hésitez pas. |
Auteur: | Samuel Devulder [ 22 Mai 2022, 15:15 ] |
Sujet du message: | Re: atan2 |
As tu vu les dernières mises à jour de viewtopic.php?p=7687#p7687 ? plus besoin d'éparpiller x/y. |
Auteur: | Bentoc [ 22 Mai 2022, 15:28 ] |
Sujet du message: | Re: atan2 |
Oui normalement c’est intégré dans mon premier post (si je n’ai rien loupé) |
Auteur: | Samuel Devulder [ 22 Mai 2022, 15:37 ] |
Sujet du message: | Re: atan2 |
Sinon dans le code d'origine Code: ; set x orcc #1 ; set carry (x < 0) tst x_h ; test sign of x using the 16 bit input value bmi > ; branch if (x > 0) andcc #$FE ; clear carry bra @a ! nega @a rol octant ; set octant b2 if x is negative Si je comprends bien: si x(16bits)<0 on ajoute 1 dans octant et on fait un neg de la partie basse. Sinon (x>=0) on injecte un 0 dans octant et on ne touche pas la partie basse. C'est ca ? Or le NEGA m'interroge. Il touche à la carry. Or si lors du "BMI >" on a bel et bien la carry à 1 à cause du ORCC juste avant, le NEGA peut la nettoyer, et le ROL injectera 0 et pas 1 comme attendu. C'est peut-être l'une des cause des erreurs de calcul. Il vaudrait mieux déplacer le ORCC juste après le NEGA en fait. Comme ca la carry serra bien positionnée avant le ROL. En plus ca fait gagner quelques cycles (on ne set pas la carry à 1 pour la passer à 0 juste après). On remarque aussi que la CARRY est exactement le bit de poids fort de x_h. On peut l'extraire en ajoutant 128 à x_h, ou encore avec une rotation. Fort de cette précédente remarque, je pense que cette partie peut être optimisée sans aucun saut. On remarque que x_h n'a en réalité que 2 valeurs possible après l'étape du "@shift": $00 ou $FF. On peut alors faire ceci: Code: LDA x_h ; A=$FF ou $00 Le EORA fait presque NEG. En fait il manque +1, mais on on s'en fiche, le code 6502 fait la même approximation. Le résultat sera juste un poil moins précis.
ASRA ; CC=1 si x_h<0, 0 sinon. Dans tous les cas A est inchangé. ROL octant EORA x_l |
Auteur: | Bentoc [ 22 Mai 2022, 15:49 ] |
Sujet du message: | Re: atan2 |
Très bonne idée ! |
Auteur: | Bentoc [ 22 Mai 2022, 16:36 ] |
Sujet du message: | Re: atan2 |
Avec ce nouveau code on tombe à 148 cycles en moyenne sur le jeu de test. On perd un poil en précision sur quelques valeurs mais rien de grave. Le cas de test suivant fonctionne toujours bien (a droite l'angle calculé) : Code: ; Y,X - Circle R=1 fdb $0000,$0001 ; 40 fdb $0001,$0001 ; 60 fdb $0001,$0000 ; 80 fdb $0001,$FFFF ; A0 fdb $0000,$FFFF ; C0 fdb $FFFF,$FFFF ; E0 fdb $FFFF,$0000 ; 00 fdb $FFFF,$0001 ; 20 ; Y,X - special case 0 fdb $0000,$0000 ; 40 code et résultats maj en page 1 Merci encore une fois Sam ! |
Auteur: | Samuel Devulder [ 22 Mai 2022, 17:07 ] |
Sujet du message: | Re: atan2 |
Quelques petites optims Code: ; compute ratio Comme C=1, SBCA B,X est identique à SUBA A,X + SUBA #1. On peut donc retirer le ORCC #1 et mettre un SUBA#1 (et pas un DECA: il ne positionne pas la retenue) iciorcc #1 ldx #log2_tab lda a,x sbca b,x ; (dynamic instruction) compute y/x ratio Code: bcs > ; branch if (x < y) Ici le ANDCC peut être remplacé par CLRB (2 cycles).nega andcc #$FE ; clear carry (x > y) Cependant si la carry dont représenter la comparaison x>y, on peut soustraire y à x, et elle serra automatiquement positionnée comme il faut sans jouer des ORCC/ANDCC. Je propose Code: ldx #log2_tab
lda a,x suba b,x bcs > eora #$FF ; pas exactement NEGA, mais ca ne change pas la carry ! ; retrieve the angle ldx #atan_tab lda a,x ; adjust octant ldb octant rolb ; set octant b0 if (x < y) andb #%111 ; modulo to keep useful values ldx #octant_adjust eora b,x ; apply octant to angle ldx #octant_adjust2 adda b,x |
Page 2 sur 2 | Heures au format UTC + 1 heure |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |