Posté le 27/11/2019 15:12
Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2025 | Il y a 102 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 02/04/2025 14:00 | #
Une idée serait de traverser le tas, ce qui te dira déjà combien y'a de leaks et leurs tailles, juste pas d'où elles proviennent. Ça c'est relativement facile. Il faut juste connaître l'allocateur, à savoir soit décompiler l'allocateur de CASIO (pour en avoir vu passer plusieurs je suis pas inquiet pour la complexité), soit consulter le code de celui de gint. Ensuite ajouter une fonction pour parcourir le tas, ce qui ne serait dur dans aucun des deux cas.
Si tu veux un truc plus complet faut pousser genre AddressSanitizer mais ça ce serait plus technique. Et si tu communiques pas avec le PC faut les infos de debug dans l'add-in ce qui est assez lourd.
Citer : Posté le 02/04/2025 17:15 | #
Hello !
J'aimerais savoir s'il y a moyen de savoir s'il y a eu des leaks dans un programme Casio comme à la Valgrind ?
Je pense que le plus facile c'est de faire fonctionner ton programme aussi sur PC (par exemple avec la SDL) et d'utiliser valgrind ici
Citer : Posté le 16/05/2025 01:34 | #
Hello ! j'ai un soucis.
Je me suis rendu compte que ma fonction qui draw mon dégradé fait pas mal ramer.
Je passe de plus 120 fps avec dclear() à 42 fps avec clear_perso()
évidement clear_perso sera remplacé par ma fonction de dégradé, ici c'est un exemple et j'obtient bien 42 fps avec celui ci .
j'ai essayé avec dma_memset et c'est encore plus lent, il n'y aurait pas une solution ?
{
long long *vram = (long long*)(gint_vram + DWIDTH * y);
long long colorLong = (color<< 16) | (color<< 48) | (color<< 32) | color;
int length = DWIDTH / 4;
for (int i = 0; i < length; i++)
vram[i] = colorLong;
}
void clear_perso()
{
for (int y = 0; y < heightInt; y++)
DrawHLine(window, y, C_BLACK);
}
Albert Einstein
Citer : Posté le 16/05/2025 01:39 | #
Donc atta 120 FPS c'est 8.3 ms, 42 FPS c'est 23 ms. Donc ta fonction supposément prend 15 ms... je vois pas comment. Une passe de remplissage de la VRAM où les calculs sont triviaux c'est 6.1 max. T'as quoi si tu mets dline() ? On peut avoir un MWE ?
Accessoirement long long sert à rien, la vitesse des accès mémoire max à 32 bits.
(Note : la VRAM est hors cache pour différentes raisons mais un access pattern linéaire donne les mêmes perfs qu'avec cache)
Citer : Posté le 16/05/2025 01:58 | #
J'ai les même perf avec dline, je vais essayé de faire un MWE à part de mon projet
mais grosso modo ma façon de calculer les fps :
std::clock_t m_startTime;
std::clock_t m_lastTime;
void time_Update()
{
std::clock_t now = std::clock();
m_deltaTime = static_cast<double>(now - m_lastTime) / CLOCKS_PER_SEC;
m_lastTime = now;
}
int FPS()
{
static double fps = 100;
if (m_deltaTime > 0)
fps = 1.0 / m_deltaTime ;
return static_cast<int>(fps);
}
void Mainloop()
{
time_Update();
for (int y = 0; y < DHEIGHT; y++)
dline(0,y,DWIDTH,y,C_BLACK);
string str = std::to_string(FPS());
dtext(0,0, C_WHITE, str.c_str());
dupdate();
}
Albert Einstein
Citer : Posté le 16/05/2025 02:20 | #
Le clock() de fxlibc utilise la RTC et a une résolution de 7.8 ms / 128 Hz. Si c'est ça que tu utilises alors les seules valeurs que ta fonction FPS peut retourner sont 128, 64, 42, 32, 25, 21, 18, 16, etc.
Elle renverra 42 FPS pour tous les intervalles de 3 ticks, une mesure qui peut sortir pour n'importe quelle durée entre ~16 ms (performance réelle 62.5 FPS) et ~30 ms (performance réelle 33.3 FPS).
Je sais que je te l'ai dit mille fois mais utilise libprof. Je comprends pas comment on peut faire des perfs avec un compteur approximatif dans un coin de l'écran !? Une mesure par frame ça ne sert à rien. Ça prend 10 minutes de faire une visualisation pour différents bouts du pipeline, c.f. genre ce screenshot de azuray. Paie-toi le luxe de mesurer que ta fonction prend 6.1 ms (... ou un chiffre similaire) et pas juste "elle perd 78 FPS, quand je pars de 120 FPS, qui sont peut-être en fait 70 parce que la fonction de mesure sait pas faire plus précis".
Citer : Posté le 16/05/2025 02:31 | #
Okay ! C'est vrai que j'ai jamais utilisé libprof.
Je vais prendre le temps de lire et tester tout ça demain et faire un MWE
En tout cas merci !
Albert Einstein
Citer : Posté le 16/05/2025 13:43 | # |
Fichier joint
Hello !
J’ai lu ton topic, que j’ai trouvé très intéressant. Cela dit, certains points m’ont paru un peu difficiles à comprendre.
Je ne saisis pas bien comment tu calcules les FPS sans effectuer une mesure à chaque frame. J’ai également consulté le code d’Azuray, et si je ne me trompe pas, il me semble que c’est ce que tu fais, non ? Ou bien accumules-tu les statistiques sur, disons, 10 frames, puis tu fais une moyenne (division par 10) que tu affiches à la 10e frame ?
Je joins le MWE pour avoir ton avis sur le code. J’aimerais savoir s’il y a des optimisations possibles à apporter.
J’ai également lu les autres sections, notamment celle sur l’assembleur. Je dois avouer que, bien que j’aie déjà un peu pratiqué, cette partie m’a complètement perdu.
Penses-tu que convertir la fonction en assembleur apporterait un réel gain de performance, sachant que j’utilise déjà des fixed-point ?
En tout cas niveau stats j'ai :
Skybox : 6517 us (153 fps)
dclear: 3745 us (269 fps)
Albert Einstein
Citer : Posté le 16/05/2025 13:48 | #
Oui c'est ce que je fais (pas d'accumulation dans ce cas). J'ai peut-être pas été très clair (le sel à 2h du matin est réel), c'est que ça suffit pas ; dans Azuray il y a la visualisation à droite qui donne les délais pour les principales parties de rendu.
Yup donc la y'a pas grand-chose à gagner. Ta skybox prend 6.5 ms et le temps qu'il faut juste pour que la RAM enregistre toutes les écritures nécessaires est 6.1 ms. Le seul moyen de gagner clairement c'est de pas dessiner la skybox là où c'est pas nécessaire. Par exemple en post-pass en cherchant les infinis dans ton zbuffer. C'est le cas d'une fonction de rendu si triviale que c'est la RAM qui est limitante. Avec Azur la même fonction prendrait probablement 0.5 - 0.6 ms (cas extrême).
Citer : Posté le 16/05/2025 14:00 | #
Okay !
Le seul moyen de gagner clairement c'est de pas dessiner la skybox là où c'est pas nécessaire.
Ça, en effet, c’est une bonne idée ! Mais est-ce qu’il n’y a pas une perte de temps en voulant lire la RAM ?
Humm... Donc tu me conseillerais d’utiliser Azur, si je comprends bien. Sauf que Azur utilise des shaders, donc ça veut dire que je suis obligé de refaire tout mon système d’affichage, non ?
J’ai aussi vu qu’Azur avait parfois des artefacts visuels.
Albert Einstein
Citer : Posté le 16/05/2025 14:08 | #
Oui mais une lecture dans le cache ça prend 1 cycle, une écriture en RAM ça prend en moyenne 13 cycles. De façon générale si tu travailles en VRAM, éviter des grandes écritures inutiles c'est rentable "par défaut".
J’ai aussi vu qu’Azur avait parfois des artefacts visuels.
Conseiller Azur je ne dirais pas forcément ça non, pour la raison que tu pointes, c'est qu'il faut changer les méthodes de dessin, donc c'est pas facile. Je le mentionne surtout parce que tu demandes "comment aller plus vite ?" et la seule réponse que je connais c'est ça.
Oui il y a quelques effets pas super super propres, tu peux en voir dans Azuray. Je sais pas si on peut les éviter facilement. Je pense pas que ça tue l'approche (la fluidité en vaut la peine) mais c'est sûr que c'est pas idéal.
Citer : Posté le 16/05/2025 14:31 | #
Donc faire ça pour toi serait moins couteux ?
inline void DrawSky(Skybox* skybox)
{
fixed12_32 rgb[3] = {skybox->rgb_start[0], skybox->rgb_start[1], skybox->rgb_start[2]};
for (int y = 0; y < DHEIGHT; y++)
{
Color color(static_cast<int>(rgb[0]), static_cast<int>(rgb[1]), static_cast<int>(rgb[2]), 255);
for (int x = 0; x < DWIDTH; x++)
{
if (z_buffer_test[x + y * DWIDTH])//c'est un exemple avec un tableau de booléen pour le test
gint_vram[x + y * DWIDTH] = color.Raw();
}
rgb[0] += skybox->rgbStep[0];
rgb[1] += skybox->rgbStep[1];
rgb[2] += skybox->rgbStep[2];
}
}
Albert Einstein
Citer : Posté le 16/05/2025 14:43 | #
Si le test zbuffer est rapide, ouais, c'est possible. Pense quand même à écrire avec des uint32_t, là tu écris en 16-bit.
Citer : Posté le 16/05/2025 14:59 | #
Si le test zbuffer est rapide
C'est à dire ? Le z_buffer_test c'est juste un tableau de uint32_t, donc on peut pas faire plus rapide que ça, si ?
Pense quand même à écrire avec des uint32_t, là tu écris en 16-bit.
Mais ça c'est quand on veut écrire 2 pixel à la fois, mais comment on fait quand un des pixel doit être écrit et l'autre non ?
Albert Einstein
Citer : Posté le 16/05/2025 15:48 | #
Oui si c'est juste un tableau très bien. Dans ton code t'as mis "exemple pour le test" donc j'étais pas sûr.
Ah oui. Euh vue la tête du test limite tu peux faire 4 cas via une sorte de switch sur deux tests de zbuffer. Mais là faudrait l'écrire en assembleur pour que ce soit rentable j'imagine.