ens-lyon-2017 / compass2018

c'est du sabotage/de l'exploitation
0 stars 1 forks source link

Des stats précises #5

Closed adud closed 6 years ago

adud commented 6 years ago

Pour avoir de bonnes stats, il serait de bon ton de calculer précisément chaque bit échangé. Alban et moi avions commencé sur notre proco, mais finalement j'avais oublié juste beaucoup trop de trucs. Dans l'idée on aurait besoin de distinguer :

adud commented 6 years ago

Et tant qu'à faire, essayer de rassembler les opcodes par catégories ci-dessus

lephe commented 6 years ago

Une chose est sûre, vous ne pouvez pas faire ça dans l'interface mémoire parce que le désassembleur et le dump de la mémoire dans le debugger vont interférer.

À mon sens, le seul endroit correct pour faire ça c'est cpu.c. Chaque instruction devrait compter elle-même la quantité de données lues. Mais c'est redondant parce que toutes les données passent déjà par disasm()... qui ne peut pas compter parce qu'elle sert aussi pour le désassembleur.

Je pense qu'une solution correcte est la suivante :

J'espère que je n'ai pas oublié de bits dans mon calcul...

Pour les catégories, il y a déjà une catégorisation dans disasm.c, vous pouvez l'étendre pour ajouter vos informations si vous voulez.

[1] Il faudra repasser sur la catégorisation de disasm.c pour s'assurer que les fonctions catégorisées comme des sauts sont exactement celles qui modifient PC autrement que pour lire leurs opérandes.

Cemoixerestre commented 6 years ago

Je suis en train d'implémenter une version légèrement différente :

Est-ce que ça vous semble correct ?

Alban

lephe commented 6 years ago

J'éviterais l'aspect « ajouter puis re-soustraire » si possible. À mon sens, si tu veux contourner le test par les catégories qui n'est en effet pas très élégant, tu peux t'en sortir en définissant une variable globale, que cpu_execute() met à 1 par défaut, qui indique si le calcul du nombre de bits se fait par différence de PC. Les instructions spéciales (setctr pc, jumpif, etc) peuvent mettre cette variable à 0 pour indiquer qu'elles font le calcul elles-mêmes.

Cemoixerestre commented 6 years ago

Je viens de pusher une première version.

Elle utilise notamment la version « ajoute puis re-soustraire » pour compter les instructions.

Bref, je ferme l'issue pour le moment, mais je ne considère pas cette version comme définitive. Si vous avez la moindre remarque, n'hésitez pas à poster des messages ici. N'hésitez pas non plus à faire des modifications.

Enfin, j'ai pas encore énormément testé cette version, il se pourrait (j'espère pas) qu'il y ait des bugs. Dans l'idéal, il faudrait comparer avec ce qu'on a fait avec Antonin pour vérifier que les deux versions sont cohérentes.

adud commented 6 years ago

Hum, peut-être aurais-tu dû tester ton code : notre version

memory interaction :

read :

total : 46548
    ins 24916   53.5275%
    dat 21248   45.6475%
    scr 384 0.824955%

write :

total : 14464
    dat 13440   92.9204%
    scr 1024    7.07965%

La tienne

-----------------------------------------------
Exchanges between the Memory and the Processor:
-----------------------------------------------

 Exchange Type    | Bits Exchanged | Proportion

 Instruction Read |     4294942504 | 100.0%
 Memory Read      |          21632 | 0.0%
 Memory Write     |              0 | 0.0%
 Get/Set Counters |          13056 | 0.0%
 Total            |     4294977192 | 100.0%

Je ne te cache pas que je suis assez vexé par le fait que tes stats semblent indiquer que je n'en branle pas une étant donné que je n'écris jamais le résultat de ma matrice…

Cemoixerestre commented 6 years ago

Oui, je viens de trouver deux erreurs : 

Bref, d'autres tests à faire

Cemoixerestre commented 6 years ago

Et on a ce qui ressemble à un underflow sur 32 bits, je regarde ça tout de suite.

icannos commented 6 years ago

Alban, pourrais-tu ajouter une option pour demander à l'émulateur de sortir les stats sous la formes:

mnemonic id_interne   nb_d'occurences
    ....     ....                    .....

Pour faciliter le chargement des codages de huffmann :p

Cemoixerestre commented 6 years ago

J'ai corrigé une erreur (j'avais oublié de compter les push parmi les échanges ^^) et ajouter l'affichage du nombre d'instructions exécutées.

Après, j'ai fait un affiche très human readable. Si tu trouves qu'il est pénible à parser pour tes arbres de Huffmann, je peux ajouter une option qui permet de décider si l'affichage est lisible pour les humains ou pour les machines.

icannos commented 6 years ago

J'ai pas trop la foi de faire le python. En revanche il faudra que le python puisse sortir un fichier avec comme format: Un entier avec la longueur max d'un opcode Puis une ligne par instruction avec mnemonic id interne taille de l'opcopde opcode. Pour pouvoir charger facilement l'encodage dans l'émulateur au lancement.

Il faudra aussi améliorer l'assembleur pour pouvoir utiliser le même fichier pour assembler avec le bon encodage. Mais pour l'instant je m'occupe que du C

lephe commented 6 years ago

J'ai modifié un peu de documentation. Si jamais vous en avez la patience, essayez de respecter les conventions utilisées jusque-là dans le code :

C'est pas pour vous embêter, mais pour éviter que ça parte en bordel. C'est aussi une règle implicite dans les projets où des contributions externes ont lieu. ;)

J'ai modifié un décompte dans write et push, qui n'écrivent pas toujours 64 bits (sauf désaccord sur l'ISA, en tous cas je ne les ai pas implémentés comme ça) ; et je ne l'ai pas modifié mais je pense que getctr est erroné puisque le processeur et la mémoire possèdent des versions synchronisées des compteurs ; ainsi en lecture il n'y a pas besoin de faire d'accès mémoire.

Edit : Je ne sais pas qui a fait un reformatage automatique de main.c mais... c'était pas vraiment nécessaire. >_<

lephe commented 6 years ago

Bon, j'ai été obligé de ressortir une version de main.c vieille de 8 commits pour annuler le reformatage automatique.

Veuillez ne pas refaire ça...

Il y a aussi des warnings très explicites sur le stack smashing que vous faites avec fscanf() dans la fonction load_encoding(). Soyez vigilants... j'ai commit des corrections. Ne laissez pas passer les warnings.

icannos commented 6 years ago

Pour le reformatage auto c'est moi: j'indente avec 4 espaces plutôt qu'avec des tabs (pour les raisons de différences de largeur des tab suivant les environnements) et mon éditeur a donc reformaté avec 4 espaces.

fdedinec commented 6 years ago

Juste pour dire merci du temps que vous y passez, que je suis grave sous l'eau pour une connerie de dépot de projet ANR jusqu'à mardi 13h, mais après je me mets à cet article, et même cela me fera des vacances. L'exploitateur

lephe commented 6 years ago

Je me rappelle qu'il restait un bug du genre underflow. Un commentaire sur sa résolution serait de bon goût au moment de fermer l'issue.

adud commented 6 years ago

Est-ce que les call et jump ont bien été comptés comme envoyant une adresse 64 bits à la mémoire ? Ils sont équivalents à un setctr pc, je crois.

Cemoixerestre commented 6 years ago

L'underflow venait des return, pour lesquels je comptais la différence au début et à la fin de l'instruction parmi la différence.

Voilà, donc si ça ne vous dérange pas, je peux refermer l'issue.

adud commented 6 years ago

Juste avant, dans ma remarque précédente, j'ai oublié return (alors que j'ai dit dans le premier commentaire de surtout pas les oublier…), qui vaut ici à une vache près setctr pc r7, donc qui va aussi envoyer 64 bits sur le fil de données. Pour le push, c'est un peu plus tendu : tel quel, il faudrait qu'on le considère comme envoyant 64 bits à SP pour faire le pré-décrément, puis 1/4/8/16/32/64 pour les données

Cemoixerestre commented 6 years ago

Remarque pertinente, je m'occuppe d'implémenter ça !

lephe commented 6 years ago

Le pré-décrément, par 64 bits ? Pas terrible ça... on a dupliqué les compteurs précisément pour éviter ce problème dans le cas du post-incrément.

Cemoixerestre commented 6 years ago

Bon, à propos des échanges, il faut qu'on fixe des règles précises.

lephe commented 6 years ago

Rapidement...

fdedinec commented 6 years ago

Le 28/03/2018 à 19:38, Cemoixerestre a écrit :

Bon, à propos des échanges, il faut qu'on fixe des règles précises.

  • Est-ce qu'on compte des bits supplémentaires pour indiquer le nombre de bits mis sur la pile par |push| Pas compris la question. Push fait passer de P vers M les bits de 2 setctr et d'un write. Le size passe une fois de M vers P parce qu'il est dans l'instruction. Comme dans un write. Mais pas dans l'autre sens.

  • Est-ce qu'on échange 64 bits lorsque l'on change la valeur d'un compteur ? 32 seulement ? Autres suggestions ? P envoie les bits poids faible en premier, et s'arrête dès qu'il n'y a plus que des zéros. Autrement dit: P lève setcounter et met select à la bonne valeur pendant juste le nombre de cycles qu'il faut. Lorsque setcounter retombe, la mémoire complète l'adresse reçue avec des zéros dans les poids forts. (avantage non négligeable, cela rend certains de vous heureux puisque les adresses négatives sont tout à coup très chères)

  • Lorsque l'on fait un |jumpif|, je dirais bien qu'on envoie la valeur du nouveau PC si le saut a été effectué, 0 bits sinon. C'est bien comme ça que c'est censé se passer ? Oui.

  • Des instructions oubliées ? Des remarques ?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ens-lyon-2017/compass2018/issues/5#issuecomment-376972348, or mute the thread https://github.com/notifications/unsubscribe-auth/APlL7WrhZp7ufnryEuiaqaVkxrlUod6yks5ti8qXgaJpZM4Svq8j.

adud commented 6 years ago

Alban, si ton code est assez souple, tu saurais-tu compiler plusieurs versions avec différentes manières de compter ? Je suis parti dans le sujet d'une version vraiment naïve (donc avec beaucoup de surcoût inutile, comme : « Que se passe-t-il si on ne dédouble pas les compteurs en mémoire ? ») à quelques améliorations qu'on pourrait faire sur notre processeur. J'ai aussi un petit « 8, ça suffit », à propos des registres.

adud commented 6 years ago

Bon ok, j'ai ajouté le morceau d'article, si c'est ok pour tous, il faudra faire des stats avec au moins la version naïve et la version la plus efficace (bon ok, sans incctr et decctr), mais dans l'idéal avec pas mal d'intermédiaires, pour voir ce qui est vraiment efficace, moyennement efficace, tout pourri, et les indiquer dans l'article.