Bonjour,
Quand je code une petite vm, comment l'optimiser pour qu'elle exécute le plus d'instruction par seconde, mais dans le bon ordre ?
Dois-je répartir la gestion dans des thread ? SI oui combien de thread créer, et à quel fréquence les faires fonctionner ? Et aussi comment faire en sorte qu'ils restent synchrone (que la ligne 1 ne soit pas exécutée apres la 2 par exemple ^^)
Sinon, quel fréquence max puis-je viser (nombre d'itération de la simulation du cycle du processeur (Execution d'un Opcode) faire par seconde sur une machine "normale" (on va dire sur un i5 par exemple, même si ici j'ai un i7 4790l))
Et plus généralement, comment la rendre la plus rapide possible (bon pas un truc pro 2 la mor ki tue nn plu )
Mercii
De quoi parles tu?
En gros, j'ai une machine virtuelle simple, j'aimerais qu'elle éxécute le plus d'opcode par seconde.
Donc, quelle est la meilleure approche
Donc je cherche a simuler la plus grosse fréquence possible de CPU, tout simplement.
oula, c'est complique comme question.
Parallelise un langage de bas niveau est essentiellement impossible. Les instructions d'un programme ont typiquement trop de dependance pour etre parallelise efficacement.
Ne faire qu'une seule boucle principale n'est pas une description bien clair. La question est combien de cycle de ton processeur il va te falloir pour emuler un cycle de la machine virtuelle. Et probablement ca depend des instructions.
Ce qui est souvent fait par les langages qui tournent sur des machines virtuelle est d'avoir une API standard qui soit implemente directement en C et pas en assembleur de la machine virtuelle.
Sinon ce que tu peux aussi faire, c'est exposer dans l'assembleur de ta machine virtuelle, des instructions qui s'executent efficacement sur ton architecture cible. Par exemple, matlab expose des notations tableau et matrices qui sont execute avec un appel a un lib blas.
Ce qui est aussi possible, c'est de cacher le resultat parsing d'instructions en langage intermediaire. Par exemple, tu peux peut-etre compiler du code specifique pour les fonctions communement utilise par un programme qui tourne sur la machine virtuelle. Ou encore, stocker une representation intermediaire.
Ce que je fais déja, c'est que l'entiereté du programme est chargée en mémoire déja.
Mais je veux simuler autant de cycle par seconde que possible (1mhz = 1 000 000 cycles par seconde? Ce serait possible?)
Ca depend de la complexite des operations, de combien de memoire ta machine virtuelle a. Mais 1Mhz n'a pas l'air difficile a emuler.
Note qu'emuler une frequence en particulier est plus difficile que d'emuler une machine pour aller aussi vite que possible.
Bah 1Mhz c'est 1 million de boucles par secondes il me semble, cela n'est pas dur ?
Ton processeur est probablement a 2Ghz, donc il fait 2 milliard de cycle par seconde. Alors si tu fais une instruction virtuelle en moins de 2000 cycles de ton processeur, alors ca va bien se passer.
Mon processeur est un i7 4790k Cadencé à 4Ghz (+- 4.4 en turbo)
Mais le soucis, comment je code cela en gardant une fréquence voulue ,car si en C++ je fais une boucle toute simple, elle ne va pas s'exécuter plusieur millions de foiis par seconde
ca depend de ce que fais ta boucle.
Une boucle toute simple genre:
for(int i=0; i< n; ++i)
sum += i;
Ca devrait s'executer a en gros 1-2 milliard de boucle par seconde.
Ouai mais ça c'est pas possible vu qu'a chaque cycle je dois fetch,decode,execute l'opcode ^^
Y'a pas moyen d'utiliser tout les coeurs du proc pour rendre la boucle plus rapide sans trop bouffer le proc ?
La JVM fait comment par exemple?
la JVM compile le bytecode en code natif.
Non, ce n'est pas possible d'utiliser plusieurs coeur pour faire ca a ce niveau la. La synchro entre les threads est trop couteuse pour pouvoir faire un pipeline fetch/decode/execute avec different core.
Je parle de la Java virtual machine, c'est une machine virtuelle non ? Donc elle émule des cycles de processeur si je me trompes pas, combien en fait-elle par seconde?
oui c'est une machine virtuelle. Mais souvent elle compile le bytecode en code natif pour eviter tous les surcout possible. Du fait, si tu fais purement de l'arithmetique le surcout de la JVM est tres faible.
Donc en gros, chaque Opcode de la JVM équivaut à un bout de code en assembleur, qu'elle compile juste à temps pour le programme?
la compilation se fait typiquement par fonction. chaque fonction est compilee pour faire la meme chose qu'une execution naive ferait.
Donc, si j'ai compri :
La JVM rencontre cela :
bipush_5
Elle va convertir ça en assembleur illico et l'envoyer au proco?
non. Elle va faire ca par fonction. probablement pas pas instruction.
Ah d'accord, je pense comprendre, elle convertis des bouts de codes entier (genre la fonction, comme tu dis) en assembleur pour l'utiliser à la demande ?
Comment elle décide quoi convertir et quoi exécuter directement?
Precisement, je ne sais pas. Mais elle fait probablement un peu de stat sur les fonctions. Si elle une fonction est appeller souvent alors elle est compile. sinon elle est interpretee.