1

yop,


Toujours omnubilé par l'exécution archive économisatrice de RAM, il m'est venu une idée ce matin.
Les ramcalls en fline ont permis l'immense progrès qui consiste à exécuter un programme en flash en utilisant les ramcalls, et par conséquence, les dll chargées par le programme via kernel::Libs*.

Inconvénient : il faut un trampoline dans la pile (une table de 'jmp xxx', méthode la plus rapide en terme de vitesse d'appel) pour accéder aux fonctions désirées dans une DLL quand on a besoin d'une fonction. Je précalcule toutes les fonctions qui me sont nécessaires à l'avance, donc le travail n'est fait qu'une fois à l'init, mais c'est quand même pas optimal, particulièrement dans le cas où une dll RO doit appeler une autre dll RO : la première dll doit, à chaque appel qu'on lui fait, faire un LibsBegin sur la seconde lib et récupérer les adresses, ça peut plomber les perfs d'un programme qui a besoin de vitesse (Par fait ça mais il n'a pas de besoin critique de vitesse).

De plus, ce mode de programmation a un inconvénient : interdiction d'utiliser des appels relogés pour les dll, les romcalls, interdiction des BSS et des relogements internes (en adresses absolues). Hors malheureusement, ce sont les appels les plus efficaces en terme de vitesse.


La solution que j'ai imaginée :
Si le programme a des adresses à reloger (relogement de dll, de romcall, relogement absolu, bss, ramcalls)
- On regarde si l'archive dispose d'une place pour le programme à exécuter. On récupère l'adresse de cette place
- On reloge le programme en RAM en fonction de sa future place
- Une fois relogé, on pousse le programme en archive, à la place convenue.

Et voilà. Si on regarde, on y gagne, pour l'exécution en archive :
- les ramcalls relogés (gain en vitesse)
- les dll calls relogés (gain en vitesse et en simplicité de programmation)
- les relogements des adresses absolues (gain en vitesse)
- les BSS (variables globales).


A noter que la section de code ne doit contenir aucune section de donnée non RO pour des raisons évidentes. Mais grâce aux BSS (dans lesquelles TIGCC met les variables globales), on retrouve l'accès à des variables globales qu'on avait perdu avec l'exécution en archive actuelle.

Les programmes susceptibles de recevoir un tel traitement par le kernel seront les programmes portant le flag RO actuel :
- aucun programme RO existant actuellement ne sera relogé à nouveau, le kernel voyant qu'il n'y à aucune table de relogement à traiter
- un programme RO contenant des tables de relogement sera transféré en RAM si nécessaire, relogé, puis poussé en archive



Voilà, c'est pas beau ça ? Immaginez un jeu de 64 ko qui utilise une lib de 64 ko de code + données statiques.
Sur AMS, il lui restera ~70 ko de RAM pour ses plans, sprites, maps et compagnies.
Avec cette méthode de relogement, il tourne avec une RAM vierge. Encore une fois, le programme dispose intégralement de la RAM quelque soit sa taille.
Qui plus est, ça permet de coder sans la moindre complication, sans aucun des inconvénients de la méthode de programmation actuelle ! On peut coder vite sans se prendre la tête pour un adressage foireux.

A noter également que les programmes RO deviendront possibles en C. En effet, on ne maitrise pas le moindre octet de son binaire final comme en ASM, surtout quand TIGCCLIB contient des paquets de relogements, donc c'est très difficile (et vraiment très chiant) de faire du RO en C.

2

Très bonne idée, j'y ai pensé, mais....

quid de l'usure accélérée de la mémoire Flash ? Ca va faire beaucoup plus de GC à faire. Dans le pire des cas une à chaque execution du programme...
Tiens ca me rappelle que dans PedroM je ne gère pas le cas où la Flash ne marche plus dans les archives... A corriger.

3

Non c'est très mauvais pour la flash.

la vraie solution serait d'avoir un adressage des BSS en relatif par rapport au contenu d'un registre dédié à cet usage.

a ce propos, aucun outil dont on dispose ne sait faire ça, pas vrai?

4

À propos de l'usure de la flash : si le programme est déjà relogé en flash, il n'y a plus besoin de le déplacer... Donc il suffit de l'écrire une seule fois, pas à chaque exécution cheeky (mais bon, c'est pas ça l'installation des flashapps ?)
Évidemment, si on inclus les BSS & Cie, ça prend de la place sad

5

PpHd (./2) :
Très bonne idée, j'y ai pensé, mais

Je m'en doutais à vrai dire.
PpHd (./2) :
quid de l'usure accélérée de la mémoire Flash ?

D'après WP ( http://fr.wikipedia.org/wiki/M%C3%A9moire_flash ), on peut tabler sur 10k fois minimum, et au mieux jusqu'à 100k. Je doute qu'on en arrive là, comme je doute qu'on tourne toujours dans le pire des cas. Ce qui veut dire qu'un programme sera mis en flash x fois avant un garbage. Qui plus est, je ne sais pas qui a lancé un même programme déjà 10k fois sur TI...

Possibilité pour reloger encore beaucoup moins que par la méthode brute (reloc à chaque run) :
- on met à un le flag 7 (non utilisé) d'un programme en flash.
- s'il utilise des libs RO, alors on vérifie qu'elles n'ont pas bougé (même test de flag).
- s'il utilise des librairies à exécution classiques (Genlib), on essaye de reloger la lib à la même place en RAM (là ça se complique, faut manipuler le heap à la main).

Côté utilisateur :
- Le kernel peut, par défaut, faire tourner les programmes à relogement en RAM. Avec un flag, il sait qu'il peut envoyer les programmes en archive.
- On peut fournir un petit utilitaire qui dégage le flag RO des programmes à relogement.

Ces mesures peuvent diminuer beaucoup l'usure, voire la supprimer si l'utilisateur le veut.



squalyl -> non, BSS == relogement. Ta vraie solution ne marchera pas, parce que pc-relatif == offset de 32ko max. Et en archive, tu peux pas adresser la RAM de là. Et pour un programme de 64 ko, c'est foutu d'avance.

Pen^2 -> C'est ce que je propose aussi, encore faut-il que des éventuels appels à des dll non RO soient vérifiés, voire remis en place.
Et en général, les BSS contiennent les vars globales, qui, dans un programme bien codé, ne devraient pas prendre trop de place (1ko de vars c'est déjà énorme).

6

pas con pour le relogement unique à chaque stockage. Ca pourrait être fait au moment de l'archivage en plus.
Folco (./5) :
squalyl -> non, BSS == relogement. Ta vraie solution ne marchera pas, parce que pc-relatif == offset de 32ko max. Et en archive, tu peux pas adresser la RAM de là. Et pour un programme de 64 ko, c'est foutu d'avance.

Je pensais pas au PC relatif, mais à un An relatif, initialisé par le kernel au lancement du programme vers un bloc de ram alloué pour ça.

et on accède au BSS par un k(an) où k est constant (offset par rapport au début du BSS dont l'adresse est dans an)

7

La méthode que je propose (pour la flash) demande une fonction supplémentaire dans l'OS :
HeapAllocAtPtr(unsigned long Size, void* Ptr);
- On regarde si on a une suite de blocs libres à partir de l'endroit indiqué et de la longueur totale demandée.
- Si oui, on ajuste les blocs d'avant et d'après pour que le heap reste cohérent
- Si non, deux solusions :
-- On fait un HeapCompress et on réessaye. Si ça marche pas, tant pis
-- On fait un HeapCompress spécial en essayant de réserver ce bloc (on écrit avant et après, mais pas dedans). Chances de succès optimales, mais c'est l'emmerde à coder je pense.

squalyl -> ça marchera en effet, mais ça ne permettrait que d'avoir des BSS en plus pour des programmes en flash. L'avantage du "tout relogement" est que ça permet également les libcalls, les ramcalls etc...

8

mouais mais déja ce serait pas mal.
on pourrait avoir du .data (initialisé) avec un memcpy() bien placé avant le main()

9

Et tu fais comment pour les programmes anciens ? De toute façon, ça laissera la manière de coder du RO compliquée.

10

Dites je rappelle qu'il faut en plus désactiver l’exécution en flash pour que ca marche...
Beaucoup de choses pour pas grand chose, non ?

11

embarrassed

12

PpHd (./10) :
Beaucoup de choses pour pas grand chose, non ?

hypno

Tu te souviens comme CF ne tournait pas sur un AMS avec une simple variable en RAM ? Le combo PFV42 + tiosmod, je trouve ça plutôt révolutionnaire mais bon...
En fait, faudrait que ça fasse l'objet d'un nouveau format de programme. Des programmes façons flash apps si on veut. Ou je ne sais quoi encore, mais qui pourrait bien changer les choses pour des monstres genre CF.

Mais bon, si ça te fait chier je comprends hein grin

13

Folco (./12) :
Tu te souviens comme CF ne tournait pas sur un AMS avec une simple variable en RAM ?


Même avec une autre variable en ROM de toute facon tongue
Folco (./12) :
Le combo PFV42 + tiosmod, je trouve ça plutôt révolutionnaire mais bon...


Bah, j'ai fait PedroM pour faire tourner un jour CF embarrassed

14

PpHd (./13) :
Même avec une autre variable en ROM de toute facon

Ah oué, donc ça change rien quoi grin
Donc pour CF 1.0, tu seras bien obligé de nous sortir une lib I2C pour les extensions de mémoire par le port IO c'est ça ? tongue
PpHd (./13) :
Bah, j'ai fait PedroM pour faire tourner un jour CF redface.gif

Excellent la philosophie, plutôt que d'optimiser le programme, on optimise l'OS grin

15

Et encore, vous avez de la chance qu'il ne soit pas possible d'overclocker la TI de manière logicielle. Suffit de voir ce que ça a donné sur les consoles où c'est possible grin
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

16

En fait, tes idées d'exécution en ROM s'appliqueraient plutôt mal à AMS j'ai l'impression. (Je sais qu'il y a moyen de faire de l'exécution tout en ROM assez propre, et PedroM pourrait probablement le faire si ce n'est déjà le cas)
Pour des BSS en ROM il y a une solution moins couteuse que ce que propose squalyl (monopoliser un registre en permanence c'est le mal), mais pareil ça ne pourrait s'appliquer sur AMS. Cette solution est d'avoir un (et un seul) emplacement mémoire fixe pour la section bss (je pense par exemple à la fin de la RAM, ça permet de ne pas couper l'espace d'adressage de la RAM en deux). Dans la pratique, ça fonctionnerait bien pour les programmes tels qu'on en trouve sur TI, qui s'accaparent toute la machine lors de leur exécution. Et y'a aussi une solution fonctionnelle pour les programmes qui veulent en démarrer d'autres, même si ce n'est pas très utile. Le seul problème ce serait les dll avec BSS (ça existe sur TI ?) pour lesquelles je ne vois d'autre solution qu'un espace en RAM (handle) alloué en permanence (mais dans ce cas, la DLL n'est pas réentrante…)
Enfin tout ça c'est théorique (c'est des trucs que je me serais bien amusé à coder a une époque… mais bon ^^), la pratique faut que quelqu'un veuille bien prendre la peine de mettre en oeuvre.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

17

GoldenCrystal (./16) :
Le seul problème ce serait les dll avec BSS (ça existe sur TI ?) pour lesquelles je ne vois d'autre solution qu'un espace en RAM (handle) alloué en permanence (mais dans ce cas, la DLL n'est pas réentrante…)

Exact, mais c'est déjà le cas des BSS avec des variables en section de code.

18

Ce que tu veux faire en fait, c'est faire des Flash Apps, non ?

19

(cf ./4 tongue)

20

Et ça serait pas possible de faire un nouveau format de programme ?
Un handle dans le header qui spécifie quel handle est attribué au programme. Un point d'entrée d'init au cas où le handle n'existe plus. Un point d'entrée main() classique si le programme est initialisé ?
Resterait le problème des liens dynamiques avec des fichiers en RAM (qui contienent des vars dans le code ou du smc), on pourrait garder , également dans le header dynamique, un pointeur vers l'endroit où ces fichiers doivent être relogés en RAM pour l'exécution.
Il faudrait donc faire un garbage de la RAM en conséquence.