On peut donc partir d' un code écrit en Basic puis soit le compiler pour obtenir sa traduction en assembleur soit le livrer au Picaxe et c' est l' interpréteur qui se débrouille
Jusque là tout va bien (c'est comme pour le type qui tombe du 18ième étage...)
( j' ai cru comprendre que l' interpréteur n' est pas situé dans le Picaxe ).
Si : il y a bien un interpréteur dans un Picaxe ; c'est même ce qui le différencie d'un PIC pur et dur.
La nuance, c'est que le code BASIC est d'abord "préparé" par PE avant d'être envoyé au Picaxe (on parle de code intermédiaire, ou de P-code)
L'objectif est d'une part d'économiser les octets et d'autre part de "faciliter" l'interprétation. Le P-code est bien plus concis que le fichier BASIC ASCII :
- tous les commentaires sont retirés,
- tous ce qui n'est pas des instructions est pré-traité : par exemple, les symbols sont remplacés par leurs valeurs,
- les instructions BASIC sont remplacés par des codes (plus concis, et plus facile à interpréter)
- les paramètres qui suivent les instructions sont codés de façon compacte et facile à utiliser.
Quelque soit le langage de programmation, tout fini ( après traduction après un interpréteur OU un compilateur ) par une suite d' instructions machine.
Sauf erreur, les ALU des PICs et des Picaxes sont les mêmes: elles éxécutent donc le même code machine pour une même fonction.
Tout à fait exact
Qqchose m' échappe:
Soit à programmer en Basic une fonction complexe qui fait appel à une suite d' instructions machine.
D' où ma crainte:
Partant d' un code écrit en Basic puis compilé en code assembleur, ce code assembleur sera-t-il optimisé.
Si oui, pourquoi le Picaxe n' en profite pas puisque le code machine est le même ?
Si l' interpréteur génère un tripotée de lignes de code (?) avant de pondre le code machine, un compilateur peut il le " nettoyer " et donner un code assembleur efficace, propre, avec le minimum de lignes d' instructions ?
En fait, la grosse différence, c'est qu'à l’exécution le Picaxe passe son temps à décoder le P-code puis à appeler des fonctions là où un PIC exécute du code machine en continu.
Le firmware d'un Picaxe contient 2 types de code machine :
- d'une part des fonctions destinées à interpréter le P-code,
- d'autre part des fonctions pré-programmées en assembleur pour être le plus performant possible, dont par exemple le serout que vous citez en exemple.
Il y a souvent un rapport énorme entre le temps nécessaire pour interpréter le P-code et celui mis par la fonction qui en résulte. Il faut par exemple des centaines d'instructions machine pour interpréter "A=A*2+B"
alors qu'une fois compilé ça ne représente plus que quelques instructions PIC.
La différence est souvent beaucoup plus faible pour des instructions complexes, comme le serout qui nécessitent de toutes façons beaucoup d'instructions machine et qui doivent être temporisées pour respecter le débit demandé.
Si vous écrivez une boucle FOR NEXT comprenant l'appel à une fonction complexe (disons WRITEMEM pour fixer les idées)
Le Picaxe passera probablement assez peu de temps dans la fonction très optimisée pour écrire en mémoire (même en assembleur, il y a différentes façon de faire et on peut faire confiance à l'éditeur pour avoir choisi la plus performante...). Mais le Picaxe doit de toutes façons passer du temps pour interpréter la boucle FOR NEXT et l'appel à la fonction qui traite réellement le WRITEMEM.
Le bilan est évidement très variable suivant la nature du programme. L'ordre de grandeur est de 1 à 1000.
Sur un serout, il n'y a pas grand chose à gagner en écrivant de l'assembleur.
Mais si vous devez recevoir des données à la volée puis les traiter et écrire sur un autre port, seul du code compilé permet une réactivité suffisante.
Pour ce qui est de la qualité du code assembleur généré à partir du BASIC, on peut effectivement craindre une moins bonne optimisation que celle obtenue à partir d'un compilateur qui n'a que cet objectif. C'est probablement une succession d'appels aux fonctions décrites ci-dessus, avec peu d'optimisation. Mais on gagne le temps d'interprétation, ce qui peut être énorme.
Par contre, pour vraiment optimiser, il faut mettre de l'assembleur entre les lignes BASIC, et là, ça va se traduire quasi directement par du code machine. L'optimisation ne dépends que de vous dans ce cas...
exemple d'optimisation en deux passes :
For i= 1 to 10000
A=B*2-4+I
next i
On remarque que B*2-4 ne dépends pas de I. Le compilateur va donc en fait effectuer :
C=B*2-4
For i= 1 to 10000
A=C+i
next i
Encore plus fort : A ne dépends pas de la valeur précédente de A dans la boucle. Donc on peut compiler :
A=B*2-4+10000
Forcément, ça va aller plus vite...