GT Turbo
4 Nov 2005, 10:44
La division executé par les deux artistes (Gpu et Dsp) n'est pas signé, en clair pas de chiffre négatif sinon cela va mal se finir, j'ai passé un petit moment a chercher le moyen le plus court de remettre le bon signe en fin d'opération et propose cela :
[code]
movei #$80000000,r21 ; le registre r21 a juste le bit de signe mis
moveq #0,r20
abs r0 ; Valeur absolue du registre r0
jr PL,Positif_0 ; le registre était positif si oui va a Positif_0
nop ; instruction bidon obligatoire
move r21,r20 ; sinon r20=$80000000
Positif_0:
abs r1 ; Valeur absolue du registre r1
jr PL,Positif_1 ; registre positif avant ? Si oui va en positif_1
nop ; pareil qu'avant
add r21,r20 ; sinon add $80000000
Positif_1:
divu r0,r1 ; pratique notre division
or r2,r1 ; rajoute le signe
Explication :
Les procs faisant tout en 32 bit, le bit de signe est le 31 (Dernier car on a un bit 0), celui est placé si bien sur la valeur est négative. J'utilises la valeur $80000000, celle ci place juste le bit de signe sur 1 donc négatif.
J'initialises un registre a 0, si le premier chiffre est négatif, ce registre passe a $80000000, ce qui nous fait un registre négatif. Si le second chiffre est aussi négatif on lui additionne $80000000 de nouveau, pourquoi c'est simple. Si on additionne $80000000 cela donne 0. Donc on se retrouve avec la règle des signes.
- + = -
- - = -
+ + = +
Ce qui fait que dans ce registre on a juste le bon signe, qu'on replace après la division par un or.
Si quelqu'un a mieux ou plus court je suis preneur.
GT Divisé :wacko:
PAs de division signee ???? j'hallucine :blink: !
Ca a l'air correct :)
Ce qui casse toute la vitesse c'est les tests :( pour l'instant je ne vois pas le moyen de les virer... a moins que...
GT Turbo
4 Nov 2005, 11:12
Azrael a trouvé mieux :
[code]
movei #$80000000,r20
move r1,r3
and r20,r3 ; on récup juste le bit de signe de r1 dans r3
move r2,r4
and r20,r4 ; on récup juste le bit de signe de r2 dans r4
abs r1 ; Absolution de r1 !!
abs r2 ; Absolution de r2 !!
div r1,r2 ; on divise r2 par r1
add r3,r4 ; on fait ta magouille sur les signes
or r4,r2 ; on rajoute le signe...
le dernier or peut etre remplacé par un add r4,r2 cela fait pareil
GT Battu par Azrael qui osera se mesurer a lui ! ;)
P.S. : Le genre de code que j'aime !! :yes:
encore plus court, mais peut etre pas plus rapide :
[code]
movei #$80000000,r20
move r1,r3
mul r2,r3 ; on fait une petite mul pour recuperer signe de r1*r2
and r20,r3 ; on récup juste le bit de signe de r3 dans r3
abs r1 ; Absolution de r1 !!
abs r2 ; Absolution de r2 !!
div r1,r2 ; on divise r2 par r1
or r3,r2 ; on rajoute le signe...
GT Turbo
4 Nov 2005, 11:22
Et m.... il va falloir compter les cycles !! :wacko:
C'est possible que ta dernière solution soit encore plus rapide, SCPCD t'en penses quoi? Pour moi c'est la plus rapide !!
GT Parti pour divisé :wacko:
enfin bon, faire une multiplication pour une division... c'est quand meme un comble !!! il n'y a vraiment pas de division signee ???? c'est une puce prehistorique, c'est pas possible !!!
Il n'y a pas une histoire de cache et d'instruction qu'il faut entrelacer pour que ca aille plus vite ?
GT Turbo
4 Nov 2005, 11:34
Azrael :
enfin bon, faire une multiplication pour une division... c'est quand meme un comble !!! il n'y a vraiment pas de division signee ???? c'est une puce prehistorique, c'est pas possible !!!
En creant ces puces, ils avaient pas d'envie de ce faire c...
Azrael :
Il n'y a pas une histoire de cache et d'instruction qu'il faut entrelacer pour que ca aille plus vite ?
J'étais en train d'y penser, le but du jeu, c'est qu'aucune instruction n'utilise un résultat calculé précédemment (Règle générale), ca pourrait donner cela :
[code]
move r1,r3
movei #$80000000,r20
mul r2,r3 ; on fait une petite mul pour recuperer signe de r1*r2
abs r1 ; Absolution de r1 !!
and r20,r3 ; on récup juste le bit de signe de r3 dans r3
abs r2 ; Absolution de r2 !!
; Ici faudrait qu'on trouve quelque chose !!
div r1,r2 ; on divise r2 par r1
or r3,r2 ; on rajoute le signe...
Faut voir avec le reste du code, dans ces cas j'utilise du code plus loin que j'insère au gré du vent :wacko: dans le code précédent. De toute façon, il faut un paquet d'instruction entre la div et le or, car on utilise r2 et la division est l'instruction la plus lente, donc faut bourrer avec le code qui suit
GT Entrelacé :wacko:
Enfin le plus pratique c'est quand meme d'ecrire une macro qui fait ca, tant pit pour les cycles perdus, a moins d'etre dans une boucle assez courte auquel cas la macro est remplacee par ce code.
Au fait, le dernier bit (celui de signe) est toujours mis a zero dans le resultat de la division ?
GT Turbo
4 Nov 2005, 11:45
Azrael :
Enfin le plus pratique c'est quand meme d'ecrire une macro qui fait ca
Pour la division ? Pour ces quelques lignes, je fais un couper coller. Et faut optimiser, car penses a la routine 3D (2 div signé par point) quand il y aura 1000 points a calculer, ce genre d'optim peut faire gagner un gros paquet de cycles.
Le plus important c'est que maintenant on a une petite routine qui va bien après c'est a ces clowns de codeur d'optimiser !! (C'est moi qui est dit cela :blink:)
GT En train d'optimisé ;)
GT Turbo
4 Nov 2005, 11:45
Azrael :
Au fait, le dernier bit (celui de signe) est toujours mis a zero dans le resultat de la division ?
Non, tout est considéré comme positif donc traité comme.
GT ;)
Je pense que la derniere est la plus rapide pour la division mais c'est IMULT et non MULT pour les multiplications signés. (:D)
ok, merci de le préciser :) quelle equipe !!
mais je n'ai pas les instructions gpu/dsp sous la main, d'ailleurs je ne sais pas comment fonctionne la puce (nombre de registres de données et d'adresse, instructions possibles avec des constantes...)
un "idiv" ca serait le pied !
Fredifredo
4 Nov 2005, 14:35
Certainement, mais il n'y a que la pratique qui permet d'optimiser le code.
GT Turbo
4 Nov 2005, 17:46
QUOTE (Azrael)
mais je n'ai pas les instructions gpu/dsp sous la main, d'ailleurs je ne sais pas comment fonctionne la puce (nombre de registres de données et d'adresse, instructions possibles avec des constantes...)
Je me fais c.. a recopier et traduire la doc Atari :
Tout sur le Gpu / Dsp
A lalala !!
GT Un copieur !! ;)
GT Turbo
4 Nov 2005, 17:53
Azrael :
un "idiv" ca serait le pied !
Non c'est un 'divs'
GT En train de corriger ce chenapan !! :p
Je veux pas trop jouer mon chieur, mais d'après ta propre traduction IMULT est une multiplication signee alors que MULT n'est pas signee, donc le pied serait quand meme d'avoir un IDIV et pas un DIVS.
Ceci dit on a un petit probleme avec la routine precedente. La multiplication prend des registres de 16 bits alors que la division en prend de 32 bit. Bref, quand on evalue le bit de signe c'est avec des registres de 16 bits. Il faudrait faire un decalage de chaque registre a multiplier pour avoir le bit de signe au bon endroit... ou bien le bit de signe est toujours en position 32 meme pour des entiers codes sur 16 bits ? Si la reponse a derniere question est vrai, alors la routine doit marcher... En fait je crois que ca marche, sinon c'est un enfer a coder... J'ai rien dit, vous pouvez aller mater la tele tranquille... moi je retourne me coucher.
Il y a un mode pour les divisions pour faire des divisions 16bits.
il faut mettre a 1 le bit du registre $F1A11C. (DIVCTRL)
GT Turbo
5 Nov 2005, 19:27
Azrael :
Ceci dit on a un petit probleme avec la routine precedente. La multiplication prend des registres de 16 bits alors que la division en prend de 32 bit. Bref, quand on evalue le bit de signe c'est avec des registres de 16 bits. Il faudrait faire un decalage de chaque registre a multiplier pour avoir le bit de signe au bon endroit... ou bien le bit de signe est toujours en position 32 meme pour des entiers codes sur 16 bits ? Si la reponse a derniere question est vrai, alors la routine doit marcher... En fait je crois que ca marche, sinon c'est un enfer a coder... J'ai rien dit, vous pouvez aller mater la tele tranquille... moi je retourne me coucher.
Bien noté, tu as raison et SCPCD derrière toi aussi, on peut faire des div sur 16 bits.
Pour l'instant je vais y reflechir, je peux enfin allumer mon Falcon et ma Jag.
GT Parti, a plus !! ;)
GT Turbo
9 Nov 2005, 10:39
Pour résumé tout cela, la routine a utilisé est celle la :
[code]movei #$80000000,r20
move r1,r3
and r20,r3 ; on récup juste le bit de signe de r1 dans r3
move r2,r4
and r20,r4 ; on récup juste le bit de signe de r2 dans r4
abs r1 ; Absolution de r1 !!
abs r2 ; Absolution de r2 !!
div r1,r2 ; on divise r2 par r1
add r3,r4 ; on fait ta magouille sur les signes
or r4,r2 ; on rajoute le signe...
GT Turbo B)
Yep, enfin c'est pas la dernière, il y a le pipelining a considerer donc la position des instructions a changer.
heuuu...on arrete et on réfléchit ?
genre (j'le fais en 8 bits) :
-20/2=-10
avec ta routine on tombe sur un $8A, négatif certes, mais pas - 10. (#-10 = $f6)
Faire mumuse avec le bit de poids fort suffit pas, trop simple ;)
A mon avis, y'a pas moyen de s'en sortir sans au moins un JR
GT Turbo
9 Nov 2005, 12:51
cts :
heuuu...on arrete et on réfléchit ?
genre (j'le fais en 8 bits) :
-20/2=-10
avec ta routine on tombe sur un $8A, négatif certes, mais pas - 10. (#-10 = $f6)
Faire mumuse avec le bit de poids fort suffit pas, trop simple ;)
A mon avis, y'a pas moyen de s'en sortir sans au moins un JR
Un très grand merci a toi (Cts) pour l'info, c'est vrai que la routine n'a pas été essayé c'était du travail théorique. Faut que j'y reflechisses plus, et surtout faire des essais.
GT En train de planté !! :wacko:
CTS, toi qui a fait de la 3D, tu n'as pas fait de division signee ?
Bah non, au pire y'a que le dividende négatif, alors je fais ça:
[code]MACRO IDIV a,b
abs
jr CC,.pos~
div a,
neg
.pos~:
ENDM
ex pour les polygones pour calcul dx/dy, on s'arrange pour que dy soit positif (cas de l'inversion point haut/point bas du segment)
ou pour la normalistation d'un vecteur, vx=vx/||v|| vy=vy/||v|| vz=vz/||v|| , la norme du vecteur v ||v|| est forcement positive.
J'suis jamais tombé sur un cas positif/negatif
Mais pitet qu'avec un XOR sur le bit de signe, on peut modifier la macros ci-dessus pour changer le signe du quotient seulement si -/+ ou +/-
GT va nous arranger ça...
bon, allez, j'my colle:
[code]
; r0=dividende
; r1=diviseur
move r0,r2
xor r1,r2
abs r0
abs r1
abs r2 ; bit de poids fort à 1 si une des operande est négative
jr CC,.positif
div r1,r0
neg r0
.positif:
me semble correct...
GT Turbo
10 Nov 2005, 10:30
cts :
me semble correct...
Pour ma part aussi, pour ceux qui ont pas encore l'habitude des sauts (Jr, Jump) faut savoir que l'instruction suivante est toujours exécuté quelque soit la condition du saut donc le div est toujours exécuté, le neg r0 ne sera exécuté que que si la condition de saut n'est pas bonne.
GT ;)
P.S. :
QUOTE (cts)
GT va nous arranger ça...
Meme pas eu le temps ^_^
Azrael
10 Nov 2005, 12:42
Merci CTS !
En 3D, dans le calcul de la matrice de changement de base tu n'as jamais eu de division negative ? En fait il se peut que le determinant a calculer soit toujours positif.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please
click here.