Help - Search - Members - Calendar
Full Version: Division signé dans les procs (Dsp, Gpu)
Jagware > Consoles > Development
GT Turbo
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:
Azrael
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
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:
Azrael
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
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:
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 !!!



Il n'y a pas une histoire de cache et d'instruction qu'il faut entrelacer pour que ca aille plus vite ?
GT Turbo
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:
Azrael
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.
Azrael
Au fait, le dernier bit (celui de signe) est toujours mis a zero dans le resultat de la division ?
GT Turbo
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
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 ;)
SCPCD
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)
Azrael
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
ça se trouve bien là dedans je suppose : http://mysite.verizon.net/res0nibn/pdf/Jag_v8.pdf ?
Azrael
Certainement, mais il n'y a que la pratique qui permet d'optimiser le code.
GT Turbo
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
Azrael :


un "idiv" ca serait le pied !





Non c'est un 'divs'



GT En train de corriger ce chenapan !! :p
Azrael
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.
SCPCD
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
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
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)
Azrael
Yep, enfin c'est pas la dernière, il y a le pipelining a considerer donc la position des instructions a changer.
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
GT Turbo
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:
Azrael
CTS, toi qui a fait de la 3D, tu n'as pas fait de division signee ?
cts
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...
cts
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
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
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.
Invision Power Board © 2001-2012 Invision Power Services, Inc.