Voir la version complète : [SDL] petit problème de vitesse
Voilà je trouve mon moteur assez lent (il utilise SDL) au niveau du chargement des images. Donc j'ai fait quelques chronométrage et je voullais savoir si c'est valeur vous semble normal ou si y aurait manière de les améliorer.
Donc les valeurs moyenne :
-chargement d'une image en BMP 24 bit de taille 800*600 : 10 millisecondes.
-chargement d'une image en PNG 24 (ac transparence) de taille 800*600 : 30 milli secondes.
J'ai réalisé mes mesures sur un pc avec un processeur à 2Gh et un autre à 1Gh.
Les valeurs obtenues sont les mêmes c'est donc que la lenteur viendrait de SDL, enfin voila, Qu'en penssez vous ?
C'est lent ça ?
non je pense que c'est normal.
Et comme le dit si bien Laurent-USA "sous windows SDL utilise DirectX 5".
Oui ca vient de la SDL qui commence à se faire un peu vielle.:p
Tu parles bien du _chargement_ depuis le disque d'une image ?
Cette vitesse dépend plutôt de la vitesse du disque dur.
Est-ce que tu as essayé de charger la même image deux fois de suite par exemple, pour voir si la seconde fois, ca n'est pas plus rapide (dans le cache du disque).
Les problèmes de lenteurs imputables à la SDL sont au niveau de l'affichage, pas vraiment au niveau chargement (charger un BMP, c'est plus ou moins copier en mémoire directement le fichier et placer quelques structures pour pointer sur les bons trucs, du moment que ca n'est pas en RLE).
Non c'est pas lent mais pas hyper rapide quand même, mais bon effectivement je peux pas y'en vouloir c'est vrai que DirectX 5 remonte un peu.
A part ca vous savez si les autres nom comme Allegro ou autre sont plus rapide ? en sachant que je suis très en retard sur mes delaits j'aimerais bien trouver une librairie assez "simple" (comme sdl). Sinon mon moteur tourne en fait avec OpenGL et SDL (elle est trops lente pour l'affichage avec la couche alpha) mais je pourrais aussi envisager d'utiliser GLUT et la lib png pour charger mes images.
voilà je vais réfléchir et vite prendre une décision.
oui bah comme tu dis mokona je vais faire ce test mais je parlait bien juste de la phase de chargement. Pour ce qui est de l'affichage je n'ai pas trop de problème puisque j'utilise opengl.
Oué bon bah après avoir chargé deux fois la même image le gain de temp n'est pas énorme et je parle bien du chargement depuis le disque dur. Comme mes disques sont rapides c'est assez bizzard peut être que je m'éttone pour rien et que j'irais pas plus vite en chargant une image avec Dx8.
Si tu as beaucoup d'images à charger et que tu trouves ca lent, tu peux peut être tout charger d'un bloc en mémoire.
Pour cela, tu concatènes tes images dans un gros fichier binaire, associé à des accès vers les débuts des fichiers réels (un .tar en gros, mais en plus simple).
Ensuite, tu utilises les fonctions (peu documentées) de SDL : SDL_RWops. Cela permet de traiter des flux binaires indépendement de leur emplacement phyique (disque ou mémoire principalement).
Tu utilises donc SDL_RWFromMem pour récupérer un RWops vers l'emplacement des débuts des fichiers en mémoire, puis tu fais charger ca par IMG_Load_RW (de SDL_Image).
C'est peut-être rentable s'il y a beaucoup d'images différentes (je t'avouerais que je n'ai pas fait le test, j'utilise cette méthode de base dans mon dernier petit projet.
Regarde aussi un chargement en .PNG avec SDL_Image plutôt qu'un BMP avec SDL pure (si c'est ce que tu fais). Le temps de décompression en mémoire est probablement plus court que le temps de chargement de l'image brute.
Bon ben merci du conseil bah je vais regarder ca de plus près et oui si je minquiette un peu c'est parce que je vais avoir pas mal d'image à charger.
Halala et dire que ca ma travailler ce problème lol, je me demandais si c'était pas moi qui était complétement nul. 8D
tyrion42
19/04/2005, 10h49
Une petite remarque, le chargement n'a rien à voir avec directx... de plus, le PNG est chargé directement par la bibliothèque officielle
quelques pistes en vrac:
Et puis, on pourrait voir ton code de chargement d'image ? est-ce un thread ? fais-tu des traitements supplémentaires ? As-tu un Anti-Virus ?
Tu pourrais poster le code et l'exe qu'on puisse comparer sur nos machines,
Bonne Journée
L'hypothèse de l'anti virus ma parrut interessante donc j'ai refait le test en désactivant mon antivirus et les valeurs n'avaient pas changées.
Sinon mon chargement d'image est sans aucun traitement, ce n'est pas un thread juste une fonction appelée par ma fonction main.
Voila donc je met le code pour ce qui est du chargement du png :
SDL_Surface *tmp;
int timerload = SDL_GetTicks();
tmp = IMG_Load("salut.png");
std::cout << "Load : " << SDL_GetTicks() - timerload << " millisecondes \n";
voila ma section de code avec le chrono.
Bon j'ai aussi mis l'exe avec les version des dll que j'ai et l'intégralité des deux fichiers source qui sont dans mon projet.
luke.qb.free.fr/sdl_test/sdl_png.zip (http://luke.qb.free.fr/sdl_test/sdl_png.zip)
Voila si quelqu'un essaye ca sur son PC et me donne ces valeurs ce serait sympa.
Voila, voila ++
Lenolian
20/04/2005, 06h38
J'ai essayé sur ma petite config, en changeant la taille de l'image :
512x512 :
Load 35 ms
Draw : 34 ms
800x600 :
Load : 75 ms
Draw : 74 ms
1024x1024 :
Load : 141ms
Draw : 54ms
Config:
AMD 866MHz
1 Go SDRAM
GeForce 2 TI 64Mo
Même si ça change pas ton temps de chargement de l'image, utilise plutot des textures puissance de 2, l'affichage sera plus rapide. Sinon pour le temps de chargement, je trouve pas ça si excessif que ça.
Mon test avec le "salut.png" de base : 50 ms en moyenne.
Maintenant, un petit calcul :
322864 octet en 50 ms, ca donne du environ 6 Mo/s. D'après hdparm, ce disque peut faire du 40Mo/s.
On est donc loin du max.
Le prochain test serait de dissocier le chargement réel en mémoire du chargement dans SDL (je n'ai pas le temps de faire ca ce matin).
tyrion42
20/04/2005, 09h13
Résultat sur mon PC au boulot (P4 2.6 MHz, 1 Go RAM, Intel 82915G/GV/910GL pour la carte graphique)
Load: 35 ms
Display: 17ms
Par contre, quelques remarques sur ton test, d'après la mailing liste
il est conseillé d'initialiser SDL avec SDL_ANYFORMAT* pour la couleur et de convertir les images destinés à être affichés via SDL_DisplayFormat ou SDL_DisplayFormatAlpha...
Mais ça ne concerne pas pb(?) de vitesse de chargement d'image
SDL_ANYFORMAT: Normally, if a video surface of the requested bits-per-pixel (bpp) is not available, SDL will emulate one with a shadow surface. Passing SDL_ANYFORMAT prevents this and causes SDL to use the video surface, regardless of its pixel depth.
Edit:
Il ne faut pas oublier que le PNG est un format très compressé, si tu veux tester la vitesse de chargement pur, passe lui un BMP !
Oui, c'est aussi un test à faire.
On pourrait s'attendre à un chargement "brut" de cette image autour de 10 ms.
Donc soit SDL fait tout un tas de trucs (comme allouer la mémoire pour charger l'image, ce qui est un minimum) soit c'est tout simplement la décompression de l'image qui est lente.
N'oubliez pas non plus que l'operating system ne fonctionne pas en real-time (à moins que tu utilises un kernel linux real-time). Donc ça veut dire que tu ne peux pas vraiment te fier à ces résultats.
Comment ça marche ? Ben en fait ton operating system alloue un certain nombres de cycles CPU pour chaque process qui tourne (en gros, sans entrer dans les détails), donc ton chargement de l'image risque d'être interrompu et 'gelé' durant un certain laps de temps (qui dépend fortment de l'OS). Donc, c'est pas vraiment fiable...
Mais une solution à ton problème serait de charger toutes tes images au début (d'ailleurs c'est comme ça que bcp de jeux fonctionnent -> d'ou l'utilisation de la 'barre de chargement' avant la partie ;) ).
J'ai fait quelques tests pour voir l'influence du format de fichier (et donc de se taille). J'ai donc un jpeg de 11Ko, des Tga (RLE et non RLE) de plus de 1,4Mo, un BMP de 1,4Mo.
Je fais la moyenne du temps de chargement de 100 chargements (histoire de stabiliser le chargement au niveau des différents caches qui peuvent exister au niveau de l'OS et de la charge OS elle même).
Résultat :
salut.png : 33 ms
salut.jpg : 18 ms
salut.tga (RLE ) : 93 ms
salut_nonrle.tga : 12 ms
salut.bmp : 8 ms
Conclusion :
- sur les deux formats "bruts" (bmp et tga sans RLE, c'est globalement un mapping direct de la surface que l'on charge), le chargement prend un temps que l'on peut estimer égal à celui du disque en prenant en compte l'influence des éventuels caches (je n'ai pas fait ça sur le même disque que ce matin, et je n'ai pas le débit de celui-là, il n'y a pas hdparam dessus).
- sur les formats compressés, il y a un temps de traitement non négligable. Le jpg est décompressé très rapidement (l'image n'est pas bien compliquée non plus), mais par rapport à sa taille (11Ko), le temps est assez grand. Le tga en RLE se prend tous les défauts : grande taille (1,4Mo) et décompression lente.
Bah merci beaucoup à tous eux qui ont essayé, pis je vois que vous avez pas des valeurs qui surpassent les mienne donc ca doit etre effectivement normal.
D'autres comme vous n'avez pas hurlez en ce qui concerne mon code source c'est qu'il doit pas y'avoir d'erreur grossière.
Donc au final je m'inquiette pas pour ce qui est du chargement, je ferais une petite barre et vue le nombre d'image que j'aurais a charger j'ai calculé ca fera environ (sur mon pc) entre 5 et 10 sec par niveau. Ce que je trouve assez raissonable.
Merci à tous ;)
Joker-eph
26/04/2005, 20h15
[QUOTE=Mokona
Maintenant, un petit calcul :
322864 octet en 50 ms, ca donne du environ 6 Mo/s. D'après hdparm, ce disque peut faire du 40Mo/s.
On est donc loin du max.
[/QUOTE]
Les disques ide ont pas très loin des 10ms de temps d'accès avant de commencer à transférer.
De plus c'est totalement indépendant de la SDL (enfin du moins j'imagine que la SDL utilise les fonctions standart open ou fopen ?).
Oui, c'est pour cela que j'ai fait le test sur la lecture de 100 fichiers. Au bout de 100 fichier on peut considérer que le fichier est de toute façon quelque part en mémoire (surtout vu la taille des fichiers) et qu'il n'est pas rechargé physiquement.
Ensuite, oui, le temps est à mon avis à 99% imputable au temps de décompression effectuées par les bibliothèques qui sont utilisées par SDL_Image.
Birdimol
20/03/2006, 10h45
Voila, je relance ce sujet car j'ai actuellement des problèmes de vitesse d'affichage dans mon jeu en sdl.
Je fais un petit zelda-like modeste pour apprendre la sdl mais le jeu est bien lent je trouve.
Je m'explique: quand je ne réaffiche que mon perso (par exemple quand il est dans le coin d'une map) le jeu va très très vite, mais si il se trouve dans un grand espace est que je dois réafficher la map qui prend toute l'écran, la ça se corse !
Comment puis-je faire pour optimiser la vitesse d'affichage ?
Vais-je etre obligé de faire mon jeu en 320*140 ?
l'image que j'utilise pour ma map est peu-etre d'une trop grande résolution ?
J'utilise bien flip(screen); et SDL_DOUBLEBUF. Malgré ça reste lent et pas très agréable...
Est-ce que le fait de convertir mon image en jpeg pour la rendre plus légère est une bonne idée? ou alors ça ne change strictement rien au niveau de l'affichage ?
Est-ce juste le nombre de pixel qui joue ?
Vos conseils ?
Utilise un temps fixe entre chaque frame (par exemple 30 msec)! Sinon, tu vas avoir des vitesses différentes en fonction du PC, des temps de calculs, .. Enfin bref, tu auras des vitesse qui vont varier complètement.
Birdimol
20/03/2006, 13h50
Ca oki, je suis d'accord :00000023:
Mais quand le jeu est trop lent a cause de l'affichage, comment faire pour l'optimiser ?
commencer à ajouter des SDL_Delay à des endroits stratégiques
vérifier que tu fais pas des boucles inutiles
vérifier que tu affiches pas d'images trop grandes sur un écran petit
vérifier que t'utilise pas d'effets superflues
Birdimol
20/03/2006, 18h02
En fait je n'ai pas trouvé de solution que de n'afficher que par déplacement de 2 pixel plutot qu'a chaque pixel. ça ne me choque pas trop, donc je suppose que c'était une bétise de vouloir afficher des déplacement pixel par pixel :00000017:
tu l'affiches comme tu veux selon la vitesse de déplacement que tu souhaites:00000005:
Lightness1024!
21/03/2006, 00h50
a mona vis ta fonction de scrolling doit pas etre super efficace.
le probleme des architectures actuelles est de devoir passer par la mémoire centrale puis de retransférer un framebuffer a travers le port graphique.
rend toi compte, un amiga avec genre un 68000 15Mhz pouvait faire du scrolling sans ramer sur des resolutions dépassant 70 000 pixels.
d'abord, les scroll ne doivent pas etre fait par pixels mais par vecteur. ton personnage n'avance pas toujours a la meme vitesse (1 pixel / image) donc -> déplacement variable.
ya peut etre moyen de locker les surface et de les faire travailler purement en hardware (device space).
une technique consisterais a utiliser opengl et de faire un glTranslatef(vecteur) sur la pile de matrices GL_TEXTURE sur un quad qui prend tout l'écran. et d'utiliser des sprites pour les détails. avec cette technique, 1000 fps garanties.
(faut pas exagérer, quand une machine peut faire tourner far cry en temps réel, tu crois qu'elle n'arriverait pas a faire défiler une bete image ?)
le probleme vient forcément du programmeur, il faut savoir relativiser.
Birdimol
21/03/2006, 09h26
Ah mais je relativise lol, je me doutes bioen que je m'y prends mal, je débute !
Bon a présent je n'affiche que par 4 pixel et ça marche nickel.
Merci pour vos réponses :00000025:
Insomniak
08/04/2006, 07h06
Bon, je re-up ce topic :00000005:
J'ai une question : est-ce que c'est beaucoups plus lent d'afficher des pnj avec de la transparence alpha plutot que d'afficher des bmp avec un sdl_colorkey ?
Merci d'avance.
hum si tu parles de
SDL_SetColorKey et SDL_SetAlpha les deux fonctions n'ont rien a voir la première définie une couleur transparente tandis que la seconde définie une transparance ou une opacité globalement à l'image.
Tu peux très bien utiisé les deux d'ailleurs, une couleur transparente et une transparence globale.
Wedge a pas compris la question :p
Insomniak se demandait si pour son jeu, il vaut mieux utiliser des sprites avec une color_key, ou s'il valait mieux exploiter un canal alpha, en terme de performances. Cela suppose bien sûr qu'il ne souhaite pas utilisé des effets liés à l'opacité directement avec ces sprites-ci (de toute façon, l'opacité n'est principalement utilie que pour les effets spéciaux, rarement pour les sprites).
Inituitivement, vu que la SDL ne passe pas par l'accélération graphique, je dirais que l'utilisation d'un canal alpha est plus lent que l'utilisation d'une color key: en effet, alors que pour la color_key l'affichage se fait en une passe, avec une couche alpha il faut d'abord rendre les canaux RVB, puis composer le résultat avec les images qui sont sous le sprite. Cela devrait donc demandait plus de temps de calcul.
Insomniak
08/04/2006, 11h38
Oups, non, en fait c'est ma faute, je tape trop vite.
Je me demandais question rapidité si des png avec une transparence alpha ou des bmp avec une transparence avec un color_key sont équivalents...
Si tu n'a pas besoin de 256 niveaux de transparence, et bien que les valeurs alpha 0 et 255 soient probablement optimisées, laisser SDL gérer une couleur transparente sera sûrement plus efficace puisque c'est fait pour ça.
Avec un rendu OpenGL, c'est encore plus vrai entre l'alpha test brut (acceptation ou rejet du fragment) et le blending.
Insomniak
10/04/2006, 18h17
Comment avoir un rendu OpenGl avec des surface sdl pour augmenter le nombre de FPS ?? Est-ce difficile ?? Mon programme tournant à 20 FPS sur un 1.5Ghz, 768 de ram et CG 64 mo, je pense que ça me serait utile. Je vais optimiser tout ça, mais si ça n'améliore pas tout ça, je vais devoir passer par un rendu OpenGl je pense.
Merci d'avance.
vBulletin® v.3.6.5, Copyright ©2000-2009, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org