Au lieu de:



PolluxJ'ai enfin eu le temps de faire un test et je ne gagne que 8% de vitesse en plus
(./330) :Je pense que c'est bien plus efficace de rajouter une version rol/ror, quitte effectivement à réenrouler la boucle (un facteur 2 ou 3 aurait un effet relativement faible sur le fps comparé à rol/ror, mais ça peut être intéressant de laisser déroulé si c'est vraiment *la* routine critique), de toute façon le gain sera gigantesque, et en plus on gagnera sur le plan de la régularité (moins de saccades puisque le pire des cas sera traité plus efficacement)

Pollux :Non, mais quand même, ce n'est pas tellement "gigantesque".
Oui, fallait pas non plus s'attendre à des miracles du style x2 ou x3
Ca devrait être un peu plus de 8% normalement (10-15% en moyenne). En tout cas le rapport gain en vitesse/taille en mémoire est bien plus élevé que pour un simple déroulage, donc tu peux réenrouler les boucles si tu préfères gagner de la mémoire.En réenroulant, je perds les 8%, donc la routine devient à peu près aussi rapide que l'ancienne (à peine plus rapide), et elle prend quand même plus de place. Le seul avantage, c'est que le fps est plus régulier.
Bon je viens de calculer, pour un groupe de 16 pixels noir & blanc avec rol : 48+2n cycles. Si tu passes à rol/ror, n passe de 15 dans le pire des cas à 9, soit un gain de presque 25% : et comme c les frames qui sont les plus lents à afficher qui vont limiter le fps dans le cas de geogeo (il _faut_ que la routine puisse tourner à 90 fps tout le temps sinon ça coince), ça peut être intéressant.Comment tu trouves 25% ?
//Collisions avec les bricks
void CollideWidthBlock (void)
{
short block_x[8], block_y[8];
unsigned char block;
short sort_n=0;
BOOL sort_flag=FALSE;
short block_sortx[8];
short block_sorty[8];
short block_sortdir[8];
BOOL flag;
short save_speed;
BOOL ReDrawMap=FALSE;
for (int i=0; i<nbrBille; i++)
{
if (Bille [i]->ypos<=BLOCKS_ENDZONE)
{
for (int j=0; j<8; j++)
{
block_x [j]=abs ((Bille [i]->xpos+Bille [i]->IMPACT_x [j])-BLOCK_SIZE2_X)>>4;
block_y [j]=abs ((Bille [i]->ypos+Bille [i]->IMPACT_y [j])-BLOCK_SIZE2_Y)/7;
//Dépassement de capacités
if (block_y [j]>17) block_y [j]=17;
}
//Trier blocks
sort_n=0;
//Parcours itération
for (int j=0; j<8; j++)
{
block=LevelMap [block_y[j]][block_x[j]];
//Si block égale à 0 quitter trie
if ((block&0x0F)==0) sort_flag=FALSE;
else
{
//Parcours listes trie
sort_flag=TRUE;
for (int k=0; k<sort_n; k++)
{
sort_flag=TRUE;
//Si block égale à liste de trie
if ((block_x [j]==block_sortx [k]) && (block_y [j]==block_sorty [k]))
{
sort_flag=FALSE;
break;
}
}
//Si trie à effectuer
if (sort_flag==TRUE)
{
block_sortx [sort_n]=block_x[j];
block_sorty [sort_n]=block_y[j];
//Direction de destruction de la brique (0=y, 1=x)
block_sortdir [sort_n++]=j;
}
}
}
//Effectuer collisions
for (int j=0; j<sort_n; j++)
{
//Extraction block
block=LevelMap [block_sorty[j]][block_sortx[j]];
//Blocks en acier (animations ou double destructions)
//Acier gris
if ((block&0x8F)==0x06) {CREATE_ANIM_BLOCK (block_sortx[j],block_sorty[j],0x06); LevelMap [block_sorty[j]][block_sortx[j]] |= 0x80;}
//Spécial en 2
else if ((block&0x8F)==0x0B) {CREATE_ANIM_BLOCK (block_sortx[j],block_sorty[j],0x0B); LevelMap [block_sorty[j]][block_sortx[j]] |= 0x80;}
//Acier jaune incassable
else if ((block&0x8F)==0x08) CREATE_ANIM_BLOCK (block_sortx[j],block_sorty[j],0x08);
//Sinon détruire
else
{
ReDrawMap=TRUE;
LevelMap [block_sorty[j]][block_sortx[j]]=0;
}
}
//Collision avec une brique
if (sort_n==1)
{
//Changement de directions
if (block_sortdir [0]<=3) AngleBille (i, 255-Bille [i]->rad);
else AngleBille (i, 128-Bille [i]->rad);
//Brique non cassé
if (LevelMap [block_sorty[0]][block_sortx[0]]!=0)
{
save_speed=Bille [i]->speed_value;
Bille [i]->speed_value=1;
BilleNoCollideWithBlock_single:
flag=FALSE;
for (int j=0; j<8; j++)
{
block_x [j]=abs ((Bille [i]->xpos+Bille [i]->IMPACT_x [j])-BLOCK_SIZE2_X)>>4;
block_y [j]=abs ((Bille [i]->ypos+Bille [i]->IMPACT_y [j])-BLOCK_SIZE2_Y)/7;
//Dépassement de capacités
if (block_y [j]>17) block_y [j]=17;
if ((block_x [j]==block_sortx[0]) && (block_y [j]==block_sorty[0]))
{flag=TRUE; break;}
}
//Si toujours dans brique
if (flag==TRUE)
{
UpdateBillePos (i);
goto BilleNoCollideWithBlock_single;
}
Bille [i]->speed_value=save_speed;
}
}
//2 briques
else if (sort_n==2)
{
//Changement de directions
if (block_sortdir [0]<=3) AngleBille (i, 255-Bille [i]->rad);
else AngleBille (i, 128-Bille [i]->rad);
//Brique non cassé
if ((LevelMap [block_sorty[0]][block_sortx[0]]!=0) || ((LevelMap [block_sorty[1]][block_sortx[1]]!=0)))
{
save_speed=Bille [i]->speed_value;
Bille [i]->speed_value=1;
BilleNoCollideWithBlock_mult2:
flag=FALSE;
for (int j=0; j<8; j++)
{
block_x [j]=abs ((Bille [i]->xpos+Bille [i]->IMPACT_x [j])-BLOCK_SIZE2_X)>>4;
block_y [j]=abs ((Bille [i]->ypos+Bille [i]->IMPACT_y [j])-BLOCK_SIZE2_Y)/7;
//Dépassement de capacités
if (block_y [j]>17) block_y [j]=17;
if (((block_x [j]==block_sortx[0]) && (block_y [j]==block_sorty[0])) || ((block_x [j]==block_sortx[1]) && (block_y [j]==block_sorty[1])))
{flag=TRUE; break;}
}
//Si toujours dans briques
if (flag==TRUE)
{
UpdateBillePos (i);
goto BilleNoCollideWithBlock_mult2;
}
Bille [i]->speed_value=save_speed;
}
}
//Si plusieurs briques
else if (sort_n!=0)
{
AngleBille (i, 128+Bille [i]->rad);
UpdateBillePos (i);
}
}
}
//Si redessiner niveau
if (ReDrawMap==TRUE) MAP_ReDrawMap ();
}
Le problème c'est pas de faire des comparaisons, c'est de faire des comparaisons avec TRUE (=1) plutôt qu'avec FALSE (=0). Une comparaison avec FALSE, c'est un simple 'tst.w' (qu'on peut même souvent supprimer), une comparaison avec TRUE, c'est un 'cmp.w #1' bcp plus gourmand en cycles et en mémoire. !x est absolument équivalent à x==FALSE, mais c'est plus rapide que x!=TRUE. Le seul avantage de !x par rapport à x==FALSE est le fait que c'est plus court, mais si tu trouves ça plus lisible avec un FALSE tu peux le laisser tel quel.
)

