Le cache est un emplacement mémoire très rapide qu'on trouve sur le processeur de la PSP. En réalité, c'est le seul composant qui tourne
réellement à la vitesse annoncée (222 MHz), les autres mémoires (comme la RAM, ou la VRAM) sont beaucoup plus lentes.
Lorsque vous lisez ou écrivez des données quelque part, celles-ci sont en réalité écrites dans le cache CPU, et non directement en mémoire. Ainsi
si vous devez accéder à ces informations plus tard, elles seront immédiatement renvoyées par le cache, car il est rapide.
Les données sont accumulées dans le cache (64 octets à la fois) et lorsque celui-ci est plein, les plus anciennes informations sont virées du cache (donc écrites en RAM à ce moment-là)
pour laisser la place aux nouvelles.
En règle générale, ce procédé est transparent: vous ne choisissez pas quelles données mettre en cache, il s'en occupe lui-même. Vous n'avez donc
même pas à savoir qu'il existe, et tout irait bien dans le meilleur des mondes... si c'était aussi simple que ça!
Sur PSP malheureusement, il n'y a pas que le processeur qui peut accéder aux différents composants comme la RAM. Par exemple, le processeur graphique
(formellement le GE sur PSP, Graphic Engine, mais que j'appellerai GPU comme pour les autres consoles) a également accès à la RAM.
Si vous voulez lui faire dessiner une image, il suffirait donc d'écrire l'image en RAM (ou en VRAM) et de lui dire de la dessiner.
Or, à cause du cache, ce n'est pas réellement possible, car l'image n'est pas réellement dans la RAM, mais dans le cache CPU!
Evidemment, le GPU n'a accès qu'à la RAM, pas au cache CPU.
Si vous faites cela vous aurez une image corrompue, car une partie est en cache, l'autre en RAM (le cache fait 32 ko, donc seule la partie la
plus ancienne de l'image sera bien en RAM, le reste dans le cache). Pour éviter ce genre de problèmes, il faudra sortir l'image du cache avant de la faire dessiner
par le GPU. C'est également nécessaire pour les palettes. Pour cela, on utilise les fonctions suivantes:
void oslUncacheImage(OSL_IMAGE *img);
void oslUncachePalette(OSL_PALETTE *pal);
Et de façon plus générale, pour sortir une plage de données du cache:
void oslUncacheData(void *data, size_t size);
Mais il faut toutefois garder en tête que c'est une opération assez coûteuse en performances, et il ne faudrait la réaliser qu'en cas de nécessité, car si vous retirez systématiquement vos données du cache, vous le rendez inutile, et les performances tomberont bien bas.
Toujours concernant les performances, il faut noter que sur PSP le cache est de 32 ko pour les données et 32 ko pour les instructions. Pour le code, il faudrait dans l'idéal faire en sorte que la boucle principale de votre jeu tienne sur les 32 ko du cache, comme ça il n'y aura pas besoin d'aller lire en RAM (qui est très lente) et vous aurez réellement la vitesse maximum du processeur (222 MHz). C'est pourquoi le fait d'optimiser le code en vitesse aux dépends de la taille (en déroulant les boucles, par exemple) aura peut-être l'effet inverse, car même s'il est exécuté plus rapidement, le fait qu'il soit plus gros réduira les performances du cache. Aussi, évitez de trop vous fier aux benchmarks, car de minuscules facteurs peuvent faire des différences énormes au final (par exemple, déplacer une fonction avant ou après une autre dans le code peut faire gagner ou perdre 10 à 20% de performances, alors que rien n'a changé excepté l'ordre).