C2P : appel aux brutes du 68000 et du C
7 sujets de 1 à 7 (sur un total de 7)
-
juste pour le fun, je voulais tester le chunky 2 planar sur un amiga 1200. ça sert à rien de nos jours, c’est juste pour s’amuser (j’ai vu les anciens posts de 2010 de screetch et amidark sur le sujet, bravo les ptis gars )
ma question ici purement au niveau du code pour les brutes des registres et toute cette sorte de chose : peut on faire plus rapide sur la dernière instruction (de 32 lignes) ci dessous ?
non pas factoriser, ça je l’avais fait c’est en commentaire juste avant mais c’est plus lent , mais y a t’il moyen d’optimiser les décalages et les masques binaires et les additions pour aller plus vite ? (en restant en C svp)
while ( (*leftMouse & 0x40) == 0x40 ) {
for (i=0; i
+ (x>>3) + bitMapBytesPerRowXy); // pour trouver les 32 bits consecutifs du bitplan,
// on va aller chercher le bon bit (en fonction du planar en cours) sur les 32 octets consécutifs du tablo chunky
// mask contient le masque pour selectionner le bon bit sur loctet (bit 0 pour le planar 0 etc)
// ensuite on redecale le bit selectionné en >>1 pour le remettre en bit 0 kelkesoit le bitplan
// et pour finir on le redecale pour le placer en ibit cad sur 1 des 32 bits consécutifs et on additionne pour le stocker en chipram
/* for (ibit=31,bit=0; bit<32; bit++,ibit--) {
(*quad) += ( ( ( chunky[x+bit+y*600] & (1<> i ) << ibit ); } * */ (*quad) = ( ( ( chunky[x+0+(y<<9)] & (1<> i ) << 31 ) + ( ( ( chunky[x+1+(y<<9)] & (1<> i ) << 30 ) + ( ( ( chunky[x+2+(y<<9)] & (1<> i ) << 29 ) + ( ( ( chunky[x+3+(y<<9)] & (1<> i ) << 28 ) + ( ( ( chunky[x+4+(y<<9)] & (1<> i ) << 27 ) + ( ( ( chunky[x+5+(y<<9)] & (1<> i ) << 26 ) + ( ( ( chunky[x+6+(y<<9)] & (1<> i ) << 25 ) + ( ( ( chunky[x+7+(y<<9)] & (1<> i ) << 24 ) + ( ( ( chunky[x+8+(y<<9)] & (1<> i ) << 23 ) + ( ( ( chunky[x+9+(y<<9)] & (1<> i ) << 22 ) + ( ( ( chunky[x+10+(y<<9)] & (1<> i ) << 21 ) + ( ( ( chunky[x+11+(y<<9)] & (1<> i ) << 20 ) + ( ( ( chunky[x+12+(y<<9)] & (1<> i ) << 19 ) + ( ( ( chunky[x+13+(y<<9)] & (1<> i ) << 18 ) + ( ( ( chunky[x+14+(y<<9)] & (1<> i ) << 17 ) + ( ( ( chunky[x+15+(y<<9)] & (1<> i ) << 16 ) + ( ( ( chunky[x+16+(y<<9)] & (1<> i ) << 15 ) + ( ( ( chunky[x+17+(y<<9)] & (1<> i ) << 14 ) + ( ( ( chunky[x+18+(y<<9)] & (1<> i ) << 13 ) + ( ( ( chunky[x+19+(y<<9)] & (1<> i ) << 12 ) + ( ( ( chunky[x+20+(y<<9)] & (1<> i ) << 11 ) + ( ( ( chunky[x+21+(y<<9)] & (1<> i ) << 10 ) + ( ( ( chunky[x+22+(y<<9)] & (1<> i ) << 9 ) + ( ( ( chunky[x+23+(y<<9)] & (1<> i ) << 8 ) + ( ( ( chunky[x+24+(y<<9)] & (1<> i ) << 7 ) + ( ( ( chunky[x+25+(y<<9)] & (1<> i ) << 6 ) + ( ( ( chunky[x+26+(y<<9)] & (1<> i ) << 5 ) + ( ( ( chunky[x+27+(y<<9)] & (1<> i ) << 4 ) + ( ( ( chunky[x+28+(y<<9)] & (1<> i ) << 3 ) + ( ( ( chunky[x+29+(y<<9)] & (1<> i ) << 2 ) + ( ( ( chunky[x+30+(y<<9)] & (1<> i ) << 1 ) + ( ( ( chunky[x+31+(y<<9)] & (1<> i ) ) ;
Partage de photos entre amis : les réseaux sociaux trop risqués ? les envois par email aléatoires ? le Cloud compliqué ? ---
Essayez album.zaclys.com ! ---
Association loi 1901, 100% made & hosted in France.Petite réponse en regardant vite fait, je pense déjà à précalculer tout ce qui ne change pas dans ton expression.
Par exemple, entre
( ( ( chunky[x+0+(y<<9)] & (1<> i ) << 31 )
et
( ( ( chunky[x+1+(y<<9)] & (1<> i ) << 30 )
on voit très bien que x+(y<<9) est constant. (1<int pos = x + (y<<9); int mask1=(1<> i ) << 31 )+ ( ( ( chunky[pos+1] & mask1 ) >> i ) << 30 )+...
par exemple…
yes bien vu pour « pos » , je men suis rendu compte hier soir
par contre pour mask1 : j’avais essayé mais ça ralentit !!!
à cause du type de variable je suppose (j’ai tenté un register ushort ) ?
quel impact le fait de mettre en register ou pas les variables des boucles ? combien de register peut on utilié au max avant de pénaliser le reste ?
est ce que le & logique entre un USHORT et un LONG est plus lourd qu’entre 2 LONG ? (le tablo de chunky[] est en LONG)
est ce que passer le tablo de chunky en SHORT serait intéressant ? ou bien non parceque de toute façon on est en 32bits et qu’il faut tout de meme un cycle ?
est ce que le fait de devoir aller chercher la valeur dans une variable c’est plus long que d’avoir en direct dans l’expression parcequ’il faut adresser la variable en mémoire et ça prend plus de cycles ? …
c’est la dessus que je n’ai pas les connaissances …
merci
Partage de photos entre amis : les réseaux sociaux trop risqués ? les envois par email aléatoires ? le Cloud compliqué ? ---
Essayez album.zaclys.com ! ---
Association loi 1901, 100% made & hosted in France.moi qui est toujours rêvé de voir ce qu’il y a dans le code, la s’est parfais, ya plus qu’as comprendre maintenant, pas si simple.
https://www.youtube.com/@sayasupa
Hello
0) Deja avec GCC tu peut faire un -S pour générer l’ASM et ainsi voir ce que ça donne
(en mettant ta fonction toute seule dans un fichier.c )
= sans même comprendre l’ASM on voit que 200 lignes ASM c mieux que 1000 ;-P
1) tu peut facilement mettre 4 vars en register et aussi 4 pointeurs et que ça passe mais à la limite tu peut décrire toutes tes variables en register et si y en a trop elles seront « dégradées » en variables normales
2) mettre ton c2P dans une routine séparée ==> permet d’avoir plus de registres libres
mais comme tu le vois un truc rapide comme ça doit utiliser 5-6 variables
3) var register: faut rester coherent dans tes formats de vars : genre faire des ULONG tout le temps ou des UBYTE tout le temps.
Ce qui est mauvais c’est de passer de ubyte à ulong car le restant du registre doit etre vide
donc il va faire un clear du registre avant de charger le UBYTE
mais si elle sert qu en UBYTE alors ce clear fut inutile
4) faut que tu sorte tout tes x y de ta formule boucle: je veut dire tu calcule ton chunky (le premier pixel à traiter) une fois au debut en prennant en compte tes x y puis tu passe aux pixels suivants chunky=chunky+pas_pour_aller_au_suivant;
5) comme déjà ecris utilise dans ta formule
register ULONG mask=i<<1; 6) je suis pas sur que la formule sur autant de lignes soit très efficace (à voir avec l ASM généré) peut être faudrait il faire un total intermediaire dans un register ULONG temp; genre temp= ( ( ( chunky[x+0+(y<<9)] & (1<> i ) << 31 ) ; temp= temp+( ( ( chunky[x+1+(y<<9)] & (1<> i ) << 30 ) ; temp= temp+( ( ( chunky[x+2+(y<<9)] & (1<> i ) << 29 ) ; […] *chunky=temp; note: utiliser *chunky comme somme temporaire impliquerait n accès mémoire 7) J’aurais tendance à « déplier la boucle » en i et à la mettre comme « inner loop » genre: calcul de chunky=…. (le premier pixel à traiter) boucle en y boucle en x { formule correspondant à i=0 (mais sans i bien sûr) formule correspondant à i=1 etc… chunky=chunky+pas_pour_aller_au_suivant; } je crois me rappeler qu’un décalage avec un registre en 68k est plus rapide qu’avec une constante
donc
register ULONG shift;
shift=31;
toto=titi<
> ne soit pas peu efficace Alain Thellier
Et en réponse à une de tes question
OUI les vars en register on tout intéret à être des ULONG car c’est des registres donc c’est aussi rapide et au moins y aura pas de conversion (genre USHORT -> ULONG)
a oui aussi si tu accede plusieurs fois le même *chunky tu as intérêt à plutot a sauver son contenu dans un var register plutot que de relire n fois la case memoire désignée par chunky
Alain
merci , je vais essayer tout ça
en tout cas ça m’éclaire déjà un peu sur les registres et les accès mémoires
Partage de photos entre amis : les réseaux sociaux trop risqués ? les envois par email aléatoires ? le Cloud compliqué ? ---
Essayez album.zaclys.com ! ---
Association loi 1901, 100% made & hosted in France.
7 sujets de 1 à 7 (sur un total de 7)
- Vous devez être connecté pour répondre à ce sujet.
› Forums › AmigaOS, MorphOS et AROS › Développement › C2P : appel aux brutes du 68000 et du C