› Forums › Communauté › Le Bar
Le forum est calme ? vive le blog de cosmos !
-
A propos de Cosmos, hier il a posé un petit quizz: https://leblogdecosmos.blogspot.fr/2018/03/petit-jeu.html
Y a-t-il encore de bons coders 68k dans la salle ?
Ou alors quelques uns qui veulent améliorer leur niveau ?
Petit jeu remue-méninge aujourd’hui que je vous propose : la routine _VectorNormalize dans Quake pèse 164 octets (40 instructions) compilée avec gcc 2.95.3. La sous-routine _DPSqrt n’a aucune importance :
[img]https://2.bp.blogspot.com/-HeF-L6nztbw/WrD-swUxWaI/AAAAAAAANxU/PKhTOoAEyoMifooA83Zb2zjTbvLpsEB2wCLcBGAs/s640/PetitJeu.jpg[/img]
Qui arrivera à l’optimiser pour un résultat final de seulement 66 octets (19 instructions) ?A vous de jouer : à gagner mon inestimable considération éternelle pour vous !
Comme j’en ai marre d’attendre qu’il accepte de publier ma réponse je la publie moi-même ici:
On parle d’optimier en nb d’instructions et pas en cycles ?
Ok, voici ma solution qui calcule:w = 1/sqrt(x*x + y*y + z*z) x *= w y *= w Z *= w
(pseudo C) en 17 instructions et 58 octets. Je crois que
c’est encore plus court que celle que tu as imaginé 😉-8<-------------------------------------------------------- _VectorNormalize move.l 4(sp),a0 ; pointeur sur vecteur fmove.s (a0)+,fp0 fmul fp0,fp0 bsr.s .addSquare bsr.s .addSquare fsqrt fp0,fp1 ; fp1=sqrt(fp0) fdiv fp0,fp1 ; fp1=sqrt(fp0)/fp0=1/sqrt(f0) bsr .mul bsr .mul .mul ; sémantique: -(a0) *= fp1 fmove.s -(a0),fp0 fmul fp1,fp0 fmove.s fp0,(a0) rts .addSquare ; sémantique: fp0 += ((a0)+)^2 fmove.s (a0)+,fp1 fmul fp1,fp1 fadd fp1,fp0 rts -8<--------------------------------------------------------
Quelques remarques:
1) J’ai viré le
fcmp fp1,fp1 fbne .whatthat?
car il est toujours vrai sauf si fp1 est un NaN chose
qui ne se produit pas dans quake.2) Le fbeq.w qui suit peut aussi être éliminé, il évite
une division par zero dont on se fiche car contrairement
aux entiers en IEEE ca ne provoque pas de TRAP mais un
INF parfaitement défini et utilisable.3) pour le calcul de 1/sqrt(w) j’utilise sqrt(w)/w ce qui
fait gagner pleins d’octets. Bien!3) j’ai factorisé les opérations concernant l’addition du carré
dans la routine locale « .add ». C’est pas optimal en cycles
cpu (quoique, vu la latence du fpu par rapport au cpu, ca se discute), mais puisque le but est de réduire le nb d’instructions
C’est aussi bien 🙂4) idem, j’ai factorisé les multiplications successives
fmove.s -(a0),fp0 fmul fp1,fp0 fmove.s fp0,(a0)
dans « .mul ». On gagne des instructions ainsi et surtout
on élimine unbsr.s .mul rts
en plaçant « .mul » au bon endroit. Re bien 🙂
5) l’optim en instructions n’est pas forcément intéressante.
Il y a dans le code de base 2 instructions plutot courtes
mais couteuses en cycles sur 68882: le fdiv et le fsqrt.
Il vaut mieux les éliminer.Je sais le faire, mais je te laisse y réfléchir Cosmos avant
de donner ma solution avec la même routine carburant un max
sur 68882 et plus. 🙂sam.
Du coup j’étends mon quizz final à toute la communauté des c0d3rz amiga. Saurez-vous éliminer le fdiv et le fsqrt ? Il me semble que j’ai déjà donné la réponse il y a quelques temps dans l’un des fils de amiga-impact.. Mais c’était passé inaperçu.
Samuel.
Amiga A500 + GVP530 (8Mo/fpu/mmu/scsi) - en panne 🙁
A500 (+ 1Mo PPS), A1200 (Blizzard-IV/fpu/64Mo)
A500 Vampire V2+ ^8^ 🙂
(mais aussi TO8, TO8D, TO9. Groupe PULS.)
- Vous devez être connecté pour répondre à ce sujet.
› Forums › Communauté › Le Bar › Le forum est calme ? vive le blog de cosmos !