1

Vu la guerre à deux balles qui vient d’avoir lieu être CoderMan, ro34v et wonderion et qu’à mon avis aurait pu être évitée si il y avait eu des benchmarks pour prouver qu’un algo est plus rapide qu’un autre.

Yaouank a déjà proposé un benchmark, mais celui-ci n’a pas fait l’unanimité être tous ces braves gens.

Donc le but du sujet est de définir des protocoles de test qui serviront de base aux discussions et sur les quels ont pourra s’appuyer pour construire des thèses.

Etant donné qu’une fonction ne peu pas tout faire autant définir plusieurs protocoles et voici ma proposition :

Je parts du principe que dans la boucle principal dans gpmain je flip le buffer après y avoir écrit toutes les images.

Pour cela le benchmark doit donner les indices de performances suivant après l’écriture de 5000 sprites dans le buffer avant de faire le flip (à un vitesse processeur donnée, par défaut 66 Mhz):

-------un indice de performace avec des sprites non clippés avec les variantes suivantes :
--------------- en 16*16
--------------- en 32*32
--------------- en 64*64
--------------- en 16*16 avec couleur de transparence
--------------- en 32*32 avec couleur de transparence
--------------- en 64*64 avec couleur de transparence
--------------- en 16*16 complètement transparents (50cheeky (16 bits uniquement)
--------------- en 32*32 complètement transparents (50cheeky (16 bits uniquement)
--------------- en 64*64 complètement transparents (50cheeky (16 bits uniquement)
--------------- en 16*16 complètement transparents (50cheeky avec couleur de transparence (16 bits uniquement)
--------------- en 32*32 complètement transparents (50cheeky avec couleur de transparence (16 bits uniquement)
--------------- en 64*64 complètement transparents (50cheeky avec couleur de transparence (16 bits uniquement)
-------- puis la même chose mais avec des sprites clippés cette fois si

-------- un indice de performace avec des sprites 320*240 non clippés avec les variantes suivantes :
--------------- avec couleur de transparence
--------------- complètement transparents (50cheeky (16 bits uniquement)
--------------- complètement transparents (50cheeky avec couleur de transparence (16 bits uniquement)
-------- puis la même chose mais avec des sprites 320*240 clippés cette fois si

L’indice de performance est basé sur le nombre de ticks nécessaire pour faire les 5000 écritures.

## complètement transparent (50cheeky (16 bits uniquement) "on voit l'objet et le fond a travers"

Voilà ma proposition.

Pour que ça soit valable il faut que ce benchmark soit open source et que tout le monde respecte le code de base, seules les fonction graphiques doivent changer, étant donné que le hardware de la gp32 est fixe pour tout le monde les écarts entre deux machines ne doit pas dépasser 1%.

2

Faut aussi que les gfx soit communs a tous les tests. smile

3

- remplacer le bit de transparence par une couleur de transparence.
- 50% transparent c'est "on voit l'objet et le fond a travers" ?
- en 8 bits et en 16bits (pas de 50% transparent en 8 bits)
- l'endroit ou on ecrit le sprite dans l'image peut changer les resultats si le code est optimise type SDK. Va falloir aussi penser a ca. Certaines routines peuvent etre hyper bien optimisee pour afficher des tiles 16x16 bien alignes sur l'ecran (et donc sans trop de possibilite de scrolling).

4

Yaouank > merci pour t'es corrections

pour le positionement des sprites dans l'écrann on peu tjs creer plusieurs paths dont un random surment le premier
ce path random devra avoir une variante pour les sprites non clippés.

je posterais le code du benchmark ce soir.

Avseth > qu'est ce que tu entends par gfx ?

5

gfx=images.

Pour le positionnement, un truc tout bete comme j'avais fait me semble pas mal pour tester la routine en situation (=le sprite qui rebondit sur les bords de l'ecran, c'est rapide a coder et le resultat est toujours le meme contrairement a un random)
Ca devrait suffire de tester un affichage statique en 0,0 et un qui bouge.

Le code du squelette du bench doit compiler sous tous les compilateurs (devkit, mrmirko, minigp32, etc.) T'inquietes pas pour ca, balance une premiere ebauche, on l'adaptera.

6

Voilà le mien que je viens de terminer à l'instant :

#include "stdlib.h"
#include "gpdef.h"
#include "gpstdlib.h"
#include "gpgraphic.h"
#include "gpmain.h"
#include "gpstdio.h"
#include "gpfont.h"
#include "gfx.h"





GPDRAWSURFACE gpDraw[2];




unsigned short BENCH=0;
void bench(void)
{
	BENCH++;
}


void Fast_Draw_Trans_Sprite_32(unsigned int x, unsigned int y,unsigned char *sprite, unsigned char color)
{
		short i,j;
		unsigned char *dest =  gpDraw[nflip].ptbuffer + (240*x + (239-y-31));
		i = 32;
		while(i--)
		{
			j = 4;
			while(j--)
                       {

                         if(*sprite != color)
                         *dest = *sprite;

                          if(*(sprite+1) != color)
			  *(dest+1) = *(sprite+1);

                          if(*(sprite+2) != color)
			  *(dest+2) = *(sprite+2);

                          if(*(sprite+3) != color)
			  *(dest+3) = *(sprite+3);

                         if(*(sprite+4) != color)
			  *(dest+4) = *(sprite+4);

			  if(*(sprite+5) != color)
			  *(dest+5) = *(sprite+5);

			  if(*(sprite+6) != color)
			  *(dest+6) = *(sprite+6);

			  if(*(sprite+7) != color)
			  *(dest+7) = *(sprite+7);

			  sprite = sprite + 8;
			  dest = dest + 8;


			}

			dest = dest + 240 - 32;
		}

}




 void GpMain(void *arg)
{

    short i;
	for( i=0; i<2; i++ )
	GpLcdSurfaceGet( &gpDraw[i],i );
	nflip=1;
	GpRectFill( NULL, &gpDraw[nflip],0,0,gpDraw[nflip].buf_w,gpDraw[nflip].buf_h,0xcc );
	GpSurfaceSet( &gpDraw[nflip] );
	for(i = 0 ; i < 2 ; ++i) GpLcdSurfaceGet(&gpDraw[i], i);
	GpSurfaceSet(&gpDraw[0]);
	unsigned long *pal = (unsigned long *)0x14a00400;
	for(i=0;i<256;i++)
	{
		pal[i]=gfx_Pal[i];
	}


	
	unsigned long max = 0;
	unsigned long min = 100000000;
	unsigned char key;
	unsigned long nb_loop;


	while(1)
	{

                GpTimerOptSet(0,1,0,bench);
	        GpTimerSet(0);
	        GpTimerSet(1);
		unsigned long count=0;
		BENCH=0;

		while(BENCH!=1)
		{

			/*GpTransBlt(NULL,&gpDraw[nflip],160-16,120-16,32,32,sprite_gfx,0,0,32,32,0);*/
			Fast_Draw_Trans_Sprite_32(160-16,120-16,sprite_gfx);
			count++;
		}
		char ben[10];
		if(count<min && nb_loop > 10)
		min = count;
		if(count>max)
		max = count;
		gp_str_func.sprintf(&ben,"%d",(max+min));
		if(nb_loop>10)
		GpTextOut( NULL, &gpDraw[nflip],10,10,ben,0x00);



		GpSurfaceFlip(&gpDraw[nflip++]);
		nflip &= 0x01;

		unsigned char *buffer = gpDraw[nflip].ptbuffer;
		memset(gpDraw[nflip].ptbuffer, 0, 320*240);
		nb_loop++;


	}
}



Ce n'est qu'une proposition à tester.
Il faut juste un header nommé gfx.h avec un sprite.

Le principe ets simple : pendant une seconde on teste le nombre d'exécution d'une routine, puis ensuite vient le flip et l'affichage (ma routine pour effacer l'écran n'est pas optimisé du tout par contre).
Au bout de 10 seconde on commence à relever les valeurs minimal et maximale et on en fait une moyenne.

J'ai testé avec une routine sur geepee32 à défaut d'avoir ma gp32 mais ça à l'air de bien fonctionner sauf que des fois ma routines allait plus vite en O2 qu'en -O3 mais maintenant qu'elle est bien optimisé c'est kif kif pour toutes les options.





7

effacer l'ecran:
memset(gpDraw[nflip].ptbuffer, 0, 320*240);

8

Ouais, en fait je voulais effacer avec des long mais je n'avais pas du mettre une bonne valeur et ça faisait des rayure almors j'ai mis des char à la place. grin
Faut dire que dans mon projet je n'ai pas besoin d'effacer l'écran car tout l'écran est remplie.

9

Raphaël :
Ouais, en fait je voulais effacer avec des long mais je n'avais pas du mettre une bonne valeur et ça faisait des rayure almors j'ai mis des char à la place. grin
Faut dire que dans mon projet je n'ai pas besoin d'effacer l'écran car tout l'écran est remplie.

Je pense que les memset, memcpy et memdup (et autres fonctions dans ce style) sont suffisament bien ecrits pour utiliser des longs quand ils peuvent.

10

Oui mais quand tu déroule la boucle un minimum, c'est plus rapide. smile

11

Bon par contre avec mon bench on pas attendre moins sur GP32 (on peut mettre 3 ou 4 secondes au lieu de 10) parce-que je laisse autant de temps pour laisser l'ordinateur se stabiliser afin que l'émulateur ne soit pas trop perturber.

12

Pour en revenir a ton code, il faudrait inserer l'idee que le X/Y du sprite ne soit pas fixe afin d'avoir une bonne approximation du temps d'affichage dans des conditions reelles.
rajouter un #ifndef gpdrawsurface au debut et redefinir vite fait les commandes su SDK utilisees. Ca doit se trouver dans les sources du SDK de mrmirko. Ca permettra de compiler le code sur tous les compilateurs, tous les SDK, toutes les distrib.
Et tu peux virer le key != key_F1 (dans l'idee d'un code qui va compiler facile partout) et le remplacer par un while(1)

Povre raphael, je fais que de l'embeter en lui disant de changer son code.

13

et afficher max, min et peut-etre la moyenne de tous les affichages depuis le debut.

14

Absolument pas ! De toute manière ce n'est qu'une proposition !
Au début je faisais une moyenne des résultats mais je voyais bien que ce n'étais pas très précis. Ca fait depuis le début de l'après midi que je le change le code ! grin

Oui je n'avais aps pensé à celui de mrmriko.
Sinon pour le key != key_F1, pas de problème, on peux le virer.

Et enfin faire varier les x et les y est une bonne idée déjà pour voir si la routine fonctionne correctement grin.

et afficher max, min et peut-etre la moyenne de tous les affichages depuis le debut.

Ouais, mais par contre il ne vaut mieux pas les enregistrer les min et max dès la première fois.

On peut aussi modifier le code pour ajouter une moyenne de toutes les valeurs sauf les extremum pour ajouter un complément... Mais quand une routine est plus rapide qu'une autre c'est net en général.

15

j'ai casiment fini le corps d emon BenchMark,

donc c'est pour bientôt smile

16

Don :
j'ai casiment fini le corps d emon BenchMark,

donc c'est pour bientôt smile

Et non, t'as pas encore fini ! tongue
Je viens de penser a un truc, il faut fixer la frequence d'horloge au debut du programme.
Je crois qu'il n'y a rien qui te certifie que la frequence soit la meme pour tout le monde si on utilise differents SDK (cf. une discussion recente je ne sais plus ou sur le forum sur la frequence par defaut de la gp32)

Pour la freq, vite fait sous la main j'ai:
//Set clock speed to 66MHz
GpClockSpeedChange(67800000, 0x69032, 3);

Mais ca passe par le sdk gamepark. Je crois que dans les sources de MrMirko t'as la version qui tourne sans aucun sdk.