30

Kevin Kofler
:
Pollux
: - ifeq 0 dans a68k

Plutôt ifne 0. smile

Oué bon, tout le monde avait compris #mac# cheeky
AS produit déjà une bonne optimisation des instructions.
Il ne faut pas considérer ça comme une optimisation, c'est juste qu'il (enfin, a68k, gtc et as-de-nitro aussi) accepte plusieurs écritures pour la même instruction...

Je n'appelle pas vraiment changer lea 8(a7),a7 en addq.l #8,a7 "accepter plusieurs écritures pour la même instruction".

Bah moralement si, si tu ne considères pas le mot "instruction" au sens strict ^^ (i.e. que t'as ràf de la représentation mémoire) L'intérêt, c'est surtout de pouvoir changer des constantes entières sans casser du code...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

31

Le self-modifying code, on en fait tout un fromage, mais franchement, c'est très très secondaire. Ca demande de connaître un peu les détails du codage de chaque instruction, ce qui n'est vraiment pas du tout nécessaire pour bien programmer en assembleur. Ca peut permettre dans certains cas de grapiller qques cycles/octets, mais bon c pas fondamental... (on peut parfaitement considérer qu'on fait comme si le code était en ROM et puis voilà)


Erf, je ne suis pas d'accord, cela peut s'avérer être une très bonne optimisation je pense, par exemple pour des routines graphiques qui gèrent différents modes (OR,AND,XOR) en N&B ou en niveaux de gris (cf: LOTRlib)
Mais je suis d'accord, ce n'est pas une priorité.

Pollux
:
regarde aussi les fonctions link, et unlink, pour créer des variables locales c'est très utile, notamment lorsque tu n'as plus de registre à ta disposition (au plus tu travailles avec des registres au plus c'est rapide)

Euh franchement c pas indispensable non plus, sauf si tu veux l'optimisation en taille à tout prix (-2 octets contre une grosse pénalité en vitesse) ou que tu fais plein de alloca() de taille variable, subq #foo,a7 et addq #foo,a7 marchent tout aussi bien (et en fait si ça se trouve tu n'en auras même pas besoin)


Tu as raison, il n'en aura peut-être pas besoin pour la fonction qu'il veut développer maintenant, mais plus tard, s'il code en ASM un "gros" projet je suis quasi-sûr qu'il sera bon qu'il utilise LINK/UNLK.
Kevin Kofler
: Pour A68k dans TIGCC, il restera tant qu'il n'y a pas d'autre solution pour compiler les programmes existants. Je compte rendre GNU as compatible avec la syntaxe A68k (avec un switch), mais je n'ai pas encore commencé ce travail.


Ah. D'accord, bon courage alors wink
Pollux
: Plus simplement : à chaque fois que tu écris du code, regarde combien de cycles et d'octets chaque instruction prend... Après, le reste viendra "naturellement"


Ce serait l'idéal oui, mais au début, des optimisations toutes faîtes, ca aide i.e. on cherche à voir ce qui fait que c'est une optimisation, et après avec une bonne documentation, on en trouve d'autre, voire même beaucoup d'autres, avec de très bonnes documentations (http://www.ticalc.org/pub/text/68k/) (^__^).

32

JM_
: Tu as raison, il n'en aura peut-être pas besoin pour la fonction qu'il veut développer maintenant, mais plus tard, s'il code en ASM un "gros" projet je suis quasi-sûr qu'il sera bon qu'il utilise LINK/UNLK.

Pas sûr. -fomit-frame-pointer est presque toujours un gain en taille (je veux dire une réduction de la taille, évidemment) comme en vitesse. On a rarement besoin d'un frame pointer.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

33

Euh... Je ne vois pas ce que tu veux dire Kevin, -fomit-frame-pointer est un switch de GCC, pas de AS, donc si l'on code en ASM "pur" il n'intervient pas... Non ?
Bref, quel qu'il en soit, je pense que l'utilisation d'un frame pointer dépend aussi de notre style de programmation.

A propos des optimisations, je pense que tu pourras utiliser celle-ci lionelA:

\label0:
...
dbf dx,\label0

en

\label1:
...
subq.w #1,dx
bge.s \label1

Le compteur de cycle intégré à VTI affiche 14 cycles pour le premier et 12 pour le second ...
C'est pas grand chose, mais bon...
Condition: distance du label tenant sur un octet
Inconvenient: 2 lignes de plus dans la source...

34

Ah, j'oubliais, si tu veux déboguer avec VTI lionelA, tu seras certainement intéressé par:

\halt: bra.s \halt

cela correspond à :

__HALT ;

en C.

Cela met le programme dans une boucle "infinie", et après tu change la valeur de registre PC avec un petit clic droit dans le débogueur de VTI.
C'est bien utile.

35

36

Merci pour tous ces conseils !
Mais juste avant de me lancer dans le codage de ma routine en asm, est-cequ'il n'y aurait pas déjà des optimisations a faire niveau algorithme ?
Auteur de Mode7 Engine pour ti68k
Auteur de F-ZERO for TI68k
Membre de Orage Studio
Mon site perso : http://www.tigen.org/lionela/
Le gite de mes parents à coté de Narbonne :
http://chaletdenis.free.fr/

37

JM_ :
A propos des optimisations, je pense que tu pourras utiliser celle-ci lionelA:

\label0:
...
dbf dx,\label0

en

\label1:
...
subq.w #1,dx
bge.s \label1
Le compteur de cycle intégré à VTI affiche 14 cycles pour le premier et 12 pour le second ...

Euh... embarrassed
- ça ne prend 14 cycles que qd Dx vaut 0 avant le dbf, ie pour la dernière itération, ça prend 10 sinon (inversement, pour le second, ça prend 14 pour les autres itérations que la dernière) -> mieux vaut regarder dans une doc, surtout que VTI fait parfois des erreurs
- ce serait subq/bcc, pas subq/bge, si dx peut être >=32768
Inconvenient: 2 lignes de plus dans la source...

Si ça n'était que ça le pb, ça pourrait se faire très facilement via une optimisation de l'assembleur ou une macro...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

38

Erf, j'ai bien fait de poster alors, j'avais des doutes, également sur VTI, maintenant j'en suis sur..
Sinon, bge marche très bien, dbf ne travaillant que sur un word.
Mais juste avant de me lancer dans le codage de ma routine en asm, est-cequ'il n'y aurait pas déjà des optimisations a faire niveau algorithme ?


Ce qui me vient à l'esprit:
Tu peux réduire le nombre des arguments passés à la fonction en définissant un format pour tes données.
Tu peux éviter les multiplications avec "mulu" utilisant les décalages de bits (lsr / lsl).
Tu peux travailler le moins possible avec des coordonées cartésiennes, utilise plutôt une adresse et un registre (c'est pas évident à gérer, mais c'est plus rapide).

Sinon, il y a le précalculé, i.e. tu mets en RAM le sprite décalé 1,2,3,4,5,6, et 7 fois, et après ca va tout seul...

Lorsque tu cherches l'adresse et le bit correspondant à un pixel sur l'écran à partir de ses coordonnées cartésiennes, fait attention au cas où les coordonnées sont négatives.

Sinon, si tu vas afficher à une adresse paire (i.e. bit de poids faible à 0) et s'il te reste encore assez de largeur du sprite à dessiner tu peux travailler sur des mots, voire peut-être même avec des mots-longs (attention que les données du sprite soient également à une adresse paire), à mon avis, si tu arrives à implémenter ne serait-ce qu'une optimisation en "word", la différencce de vitesse sera significative. (je l'ai fait pour une routine de ligne horizontale, pour une routine de remplissage de rectangle, et pour une routine de remplissage de triangle, il n'y a pas photo, c'est bien plus rapide, alors je pense que pour une routine d'affichage de sprites il en sera de même.)

Sinon, je pense qu'en utilisant un écran (240xh) virtuel (tiens, un petit frame pointer ;-)), sur lequel tu copies ton sprite rapidement (move)
soit en (x-mod(x,8);y), puis tu décales toute la partie entre y_clip_min et y_clip_max vers la droite avec une belle boucle de roxr.w (a0)+
soit en (x-mod(x,8)+8;y), puis tu décales toute la partie entre y_clip_min et y_clip_max vers la gauche avec une belle boucle de roxl.w -(a0)
Selon ce qui est le plus rapide.
Il ne reste plus qu'à appliquer alors la partie qui t'intéresse de l'écran virtuel sur l'écran, avec la bonne opération logique et des masks pour le clipping à droite et à gauche.
Pour ce qui est du mask du sprite, je n'en ai jamais utilisé, mais tu devrais pouvoir le gérer avec cette méthode.
Je pense qu'elle donnera quelque chose de plus rapide que de décaler chaque octet du sprite un à un...
Enfin, c'est une idée comme cela, je m'y pencherai plus dessus les vacances prochaines...

Bon courage !

39

JM_ :
Erf, j'ai bien fait de poster alors, j'avais des doutes, également sur VTI, maintenant j'en suis sur.. Sinon, bge marche très bien, dbf ne travaillant que sur un word.

N'importnawak : essaye de voir ce qui se passe avec d0 = 0x8765...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

40

JM_ :
Euh... Je ne vois pas ce que tu veux dire Kevin, -fomit-frame-pointer est un switch de GCC, pas de AS, donc si l'on code en ASM "pur" il n'intervient pas... Non ?

C'est un switch qui intervient sur le code assembleur produit par GCC, et justement il dit à GCC de ne pas utiliser link dans la plupart des fonctions.
A propos des optimisations, je pense que tu pourras utiliser celle-ci lionelA:

\label0:
...
dbf dx,\label0

en

\label1:
...
subq.w #1,dx bge.s \label1

Pas vraiment... (Cf. les autres messages.) Mais j'en ai une vraie qui ressemble:
 subq.w #1,%dn
0:
 ...
 dbf %dn,0b

en:
1:
 ...
 subq.w #1,%dn
 bne.s 1b

(économise 2 octets).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

41

101209 ms eek !!!

42

Erf oui, j'ai dit n'importe quoi. Désolé.

43

Hum désolé c'est de ma faute, je parlais du temps de génération de cette page web quand j'y ai accédé hier soir.