Page 1 of 7

Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 09 Dec 2017, 19:07
by Admin
Comme rappelé récemment dans l'épisode 19 de notre classement QCC de rentrée 2017, la HP Prime était depuis la rentrée 2013 la calculatrice graphique la plus rapide. Mais lors de la mise à jour de cet épisode suite à la sortie de la calculatrice NumWorks, nous remarquions que la NumWorks semblait la dépasser en performances (testées sur l'évaluation de programmes de calcul numérique).

Avec un processeur cadencé quatre fois moins vite, ARM Cortex-M4 à 100MHz pour la NumWorks contre ARM9 (ARMv5) à 400MHz pour la HP Prime (à moins que cette dernière information répandue sur Internet ne soit que la fréquence nominale et non la fréquence réelle ?) c'était assez surprenant. Nous ne pouvions exclure une erreur de mesure, les écarts ne faisant que quelques centièmes de seconde. En effet notre protocole de test utilisait le même programme pour tous les modèles, programme que l'on ne pouvait pas corser davantage à cause de limitations sur les modèles les plus faibles, et qui donc sur les meilleurs modèles terminait en moins d'une seconde, faisant ainsi perdre aux mesures en précision.

Aujourd'hui que le langage de programmation Python de la NumWorks n'est plus en version beta, et que la HP Prime gère aussi une forme de Python, tentons d'éclaircir un petit peu le mystère entourant les différences de performances entre ces deux modèles, et de les départager équitablement.

Nous allons cette fois-ci tester les performances avec un programme graphique. Reprenons le programme Mandelbrot inclus en exemple sur la NumWorks, et adaptons-le à l'identique pour la HP Prime. Nous ne dessinerons donc dans les deux cas que 320x222 pixels au lieu 320x240, puisque les écritures sur la barre de titre sont bloquées sur la NumWorks ce qui pourrait fausser la comparaison.

programme NumWorks en Python
(versions 1.2.0+)
programme HP Prime en simili-Python
(versions 12951+)
Code: Select all
import kandinsky
def mandelbrot(W,H,N) :
for x in range(W):
  for y in range(H):
   z=complex(0,0)
   c=complex(2.7*x/(W-1)-2.1,-(1.87*y/(H-1)-.935))
   j=0
   while j<N and abs(z)<2:
    j=j+1
    z=z*z+c
   t=255*j/N
   col=kandinsky.color(int(t),int(.75*t),int(.25*t))
   kandinsky.set_pixel(x,y,col)
Code: Select all
#cas
def fractal_python(W,H,N) :
local x,y,z,c,j,t,col
for x in range(W):
  for y in range(H):
   z=0
   c=2.7*x/(W-1)-2.1-i*(1.87*y/(H-1)-.935)
   j=0
   while j<N and abs(z)<2:
    j=j+1
    z=z*z+c
   t=255*j/N
   col=RGB(IP(t),IP(.75*t),IP(.25*t))
   PIXON_P(x,y,col)
FREEZE
WAIT(0)
#end


La NumWorks met seulement 1min26s à effectuer le tracer pendant que la HP Prime se traîne péniblement pendant 4min22s. On confirme donc, hélas, des performances très décevantes pour la HP Prime, le même programme mettant 3 fois plus de temps à allumer le même nombre de pixels. :'(

Notons que dans les deux cas, on peut voir à l’œil nu les pixels s'allumer progressivement de haut en bas sur chaque colonne, ce qui suggère bien un fonctionnement similaire des instructions graphiques, légitimant ainsi la comparaison.

Bien que les TI-Nspire disposent d'un Python non officiel, nous ne pouvons y exécuter exactement le même programme et c'est pour cela qu'elles sont absentes de ce test. En effet, les fonctions graphiques de l'évaluateur Python en question fonctionnent différemment et ne permettent pas d'écrire directement sur l'écran, obligeant à définir et écrire des zones hors écran (offscreen) qui seront remplies puis affichées d'un seul coup. Un très mauvais choix d'ailleurs dans le contexte scolaire de lycéens débutants d'imposer ce fonctionnement, alors qu'au contraire il faudrait leur laisser expérimenter l'écriture directe et en saisir les limites pour qu'il puissent alors comprendre l'intérêt de passer par une zone 'offscreen'. Pas possible non plus de choisir un autre langage interprété comme le TI-Basic, puisqu'il ne dispose pas de fonctions de sorties graphiques sur ces modèles. Le Lua n'est pas non plus une solution puisqu'il ne gère pas les nombres complexes d'une part, obligeant donc à passer par divers astuces risquant de fausser la comparaison, et d'autre part 'bufferise' les sorties écran, les temporisant donc pour les rendre effectives de façon groupée en fin d'exécution de la fonction de rafraîchissement on.paint(gc).



Pourquoi la HP Prime est-elle si lente ? Deux hypothèses :
  1. soit on incrimine le CAS, le langage simili-Python de la HP Prime n'étant disponible que dans le contexte CAS, et nous avions vu dans l'épisode en question que les calculs étaient nettement plus lents dans ce cadre
  2. soit on incrimine son évaluateur/traducteur Python

Pour valider ou infirmer cette dernière hypothèse, traduisons le même programme dans le langage interprété HPPPL CAS originel de la HP Prime :
Code: Select all
#cas
fractal_cas(w,h,n)
BEGIN
local x,y,z,c,j,t,col
FOR x FROM 0 TO w-1 DO
  FOR y FROM 0 TO h-1 DO
   z:=0
   c:=2.7*x/(w-1)-2.1-i*(1.87*y/(h-1)-.935)
   j:=0
   WHILE j<N AND abs(z)<2 DO
    j:=j+1
    z:=z*z+c
   END;
   t:=255*j/N
   col=RGB(IP(t),IP(.75*t),IP(.25*t))
   PIXON_P(x,y,col)
  END;
END;
FREEZE
WAIT(0)
#end

[

Et bien c'est pire, la HP Prime passant de 4min22s à 4mins35s. Ce qui implique que l'écriture à la Python ne complexifie pas la chose, et le temps additionnel étant probablement dû à l'évaluation des lignes supplémentaires de fin de bloc qui sont omises en Python.



Ce serait donc la faute du CAS ? Voyons si nous pouvons valider cette hypothèse en réécrivant le même programme en langage interprété HPPPL non-CAS :
Code: Select all
EXPORT fractal(w,h,n)
BEGIN
local x,y,z,c,j,t,col
FOR x FROM 0 TO w-1 DO
  FOR y FROM 0 TO h-1 DO
   z:=0
   c:=2.7*x/(w-1)-2.1-i*(1.87*y/(h-1)-.935)
   j:=0
   WHILE j<N AND abs(z)<2 DO
    j:=j+1
    z:=z*z+c
   END;
   t:=255*j/N
   col=RGB(IP(t),IP(.75*t),IP(.25*t))
   PIXON_P(x,y,col)
  END;
END;
FREEZE
WAIT(0)
#end


Bien, la HP Prime tombe cette fois-ci à seulement 2min24s, doublant presque ses performances. Le contexte CAS limite bien les performances même quand on ne fait pas appel à ses spécificités, et il est ainsi dommage que le langage simili-Python ne soit donc disponible que dans ce cadre, surtout quand il n'y a aucune intention de faire du calcul exact ou littéral.

Toutefois, 2min24s c'est quand même nettement plus lent que les 1min26s de la NumWorks. D'autres facteurs interviennent donc visiblement, et l'on peut valider la constatation de l'épisode 19.

Cela ne veut pas forcément dire que son processeur est plus puissant, mais en tous cas en terme de performances effectives et ce depuis la rentrée 2017, la meilleure calculatrice graphique est donc la NumWorks. :bj:

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 09 Dec 2017, 20:42
by parisse
Le langage CAS de la Prime est plus lent que le non CAS ou que Python, c'est parfaitement normal, parce qu'il y a plus de types a gerer pour l'interpreteur: un nombre complexe CAS peut avoir une partie reelle et imaginaire entier (ou flottant multi-precision ou intervalle sur Xcas ou KhiCAS, on peut donc certifier un calcul avec des complexes approches). Vous pouvez ameliorer les temps d'execution en utilisant une boucle contenant une seule instruction, a faire pour la boucle interieure, en remplacant la boucle while par une boucle for de la maniere suivante
Code: Select all
for j in range(N):
   if abs(z=z*z+c)>2:
     break

qui est traduit en langage Xcas en
Code: Select all
for j from 0 to N-1 do
  if abs(z:=z*z+c)>2 then break; fi;
od;

De memoire, il faut 170 secondes pour faire le Mandelbrot sur la Prime en 320x240 avec le CAS.
D'autre part, je n'ai pas passe beaucoup de temps a optimiser l'interpreteur CAS pour deux raisons: d'abord parce que je consacre l'essentiel de mon temps a developper des commandes mathematiques, ensuite parce que si on veut des performances, utiliser un langage interprete n'est pas une bonne idee (et une calculatrice non plus). Plutot que d'essayer d'optimiser l'interpreteur, je travaille sur une traduction automatique vers C++ puis compilation, ainsi dans Xcas sous Linux, vous pouvez compiler certains programmes CAS en C++ via la commande cpp(nom_de_la_fonction_CAS), par exemple le Mandelbrot que vous pouvez trouver dans le menu Aide>Exemples>demo. Observez que dans ce script, les variables sont typees, pour que le traducteur vers C++ choisisse le bon type. Cela peut etre egalement utile dans un contexte d'enseignement, en permettant un controle de type a l'execution, ce qui n'est pas possible il me semble en Python (sauf explicitement).
Cython permet de faire des choses analogues en Python.

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 09 Dec 2017, 20:57
by critor
Merci pour les précisions ainsi que pour l'astuce. :)

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 09 Dec 2017, 21:16
by parisse
Une autre remarque a propos de performances. Les langages interpretes ne posent pas de problemes de performances, des l'instant que les boucles interieures sont evitees, par l'emploi d'une instruction builtin du langage. Par exemple si l'instruction de la boucle interne est une multiplication de matrice nxn avec n grand. Du coup, les utilisateurs de langages de ce type ont pris l'habitude d'ecrire de maniere tres "fonctionnelle" ou algebrique pour justement faire cela. Cela cree un biais dans le style de programmation et peut-etre aussi a l'importance accordee a savoir programmer les choses de base soi-meme vs utiliser des commandes du langage a la complexite pas toujours bien maitrisee.
Cette dichotomie n'existe pas dans les langages compiles, c'est pour cela que je trouve extremement dommage que les eleves de prepa n'apprenent pas obligatoirement un langage compile. Apres tout, on leur apprend beaucoup de maths fondementales qui ne leur serviront pas apres, on pourrait aussi leur apprendre les fondements de la programmation sans biais.

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 09 Dec 2017, 22:13
by critor
Pour référence puisque nous n'avons pas pu tester les principaux modèles sur cet exemple, le diagramme de la mise à jour de l'épisode 19 qui semble se confirmer malgré les imprécisions de mesures :
Image
  1. NumWorks, processeur 32-bits ARM Cortex-M4 à 100 MHz
  2. HP Prime, processeur 32-bits ARM9(ARMv5) à 400 MHz
  3. TI-Nspire monochromes, processeur 32-bits ARM9(ARMv5) à 120 MHz
  4. TI-Nspire CX, processeur 32-bits ARM9(ARMv5) à 156 MHz
  5. Casio Graph 90+E, processeur 32-bits SH4 à 116 MHz
  6. Casio Graph 35/75+E, processeur 32-bits SH4 à 12 MHz
  7. Casio Graph 25+E, processeur 32-bits SH4 à 12 MHz
  8. TI-84 Plus T, processeur 8-bits z80 à 15 MHz
  9. TI-82 Advanced, processeur 8-bits z80 à 15 MHz
  10. TI-84 Plus CE, processeur 8-bits eZ80
  11. TI-83 Premium CE, processeur 8-bits eZ80
  12. Casio fx-CP400+E, processeur 32-bits SH4 à 116 MHz
  13. Lexibook GC3000FR, processeur :troll:

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 10 Dec 2017, 07:34
by parisse
Il est un peu premature de comparer les performances de deux calculatrices sur un seul exemple, le Mandelbrot teste ici les operations sur les nombres complexes. Quelle est la vitesse de la Numworks sur le programme du QCC? Le module fractions ne semble pas disponible sur la Numworks, dommage ca aurait permi de comparer un aspect du calcul exact.
Mais de toutes facons, comme je l'ai dit plus haut, en langage interprete, on va essayer d'utiliser des instructions de haut niveau, donc les performances des programmes dependent beaucoup de l'existence et de la vitesse de ces commandes, par exemple en arithmetique ou en calcul matriciel.

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 10 Dec 2017, 12:13
by parisse
Autre astuce pour aller un peu plus vite, precalculer certains facteurs, en particulier t qui est un rationnel dans la version de depart (la boucle la plus interne n'est souvent executee qu'une ou deux fois, optimiser la boucle sur y fait sens). Ce qui donne le code suivant qui devrait etre un peu plus rapide:
Code: Select all
def fractal_python(W,H,N) :
local x,y,z,c,j,t,w,h,n
w=2.7/(W-1)
h=1.87/(H-1)
n=255.0/N
for x in range(W):
  for y in range(H):
   z=0
   c=w*x-2.1-i*(h*y-.935)
   for j in range(N):
    if abs(z=z*z+c)>2:
      break
   t=n*j
   t=RGB(IP(t),IP(.75*t),IP(.25*t))
   PIXON_P(x,y,t)   

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 10 Dec 2017, 13:07
by critor
Sur le programme de calcul numérique réel du QCC (on exclut donc les calculs complexes et les sorties graphiques), la NumWorks était également nettement devant.

Je ne prétends pas que l'on ne puisse pas trouver de situation particulière où la HP Prime s'en sort mieux, ni même que son processeur soit inférieur.
Mais visiblement, sur les premiers exemples testés et qui n'ont donc absolument pas été construits pour donner cette impression (et pour le QCC c'était quasiment le même que l'année dernière), la NumWorks est nettement plus performante.

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 10 Dec 2017, 13:23
by critor
Et puis, je trouve que nous n'avons absolument pas été pressés d'annoncer cela, et avons pris le temps de confirmer avant d'annoncer n'importe quoi, comme toujours.
D'ailleurs, les vidéos datent de près d'une semaine et la constatation de quelques jours avant (beta pour préparer la news d'annonce du firmware 1.2.0, personne ne pensant je pense que l'on a pondu ça en 30 minutes après déjeuner le jour de la sortie). Nous avons de plus pris le temps d'échanger à plusieurs à ce sujet avant d'annoncer quoi que ce soit, c'est dire.
Les écarts sont significatifs et sans appel.

Ce n'est pas une information nouvelle, c'est juste que nous ne l'avions pas mise en avant. Cela a déjà été dit en commentaire de l'épisode 19 en août dernier, mais avec un doute sur la précision des mesures tellement ça paraissait illogique face à la supposée puissance écrasante du processeur HP Prime (générations très proches et quatre fois plus cadencé, sauf si la fréquence effective de la puce diffère de sa fréquence nominale qui aurait donc été répandue à tort partout sur Internet).

Nous avons pris le temps donc de tester avec un programme dédié, et de le porter absolument à l'identique pour mettre les deux modèles dans les situations les plus proches possibles.
Nous avons même pris le temps de tester la HP Prime dans différents langages et contextes (CAS+Python, CAS+HPPPL, non-CAS + HPPPL). Même si ça varie dans tous les cas la HP Prime est nettement derrière, même dans le meilleur des cas.

Aucune idée pour les sorties graphiques, mais comme cette différence semble apparemment transversale, on peut supposer que cela vient au moins du moteur de calcul. N'aviez pas déjà parlé d'une histoire de base 2 et de base 10 ?

On peut toujours améliorer le programme HP Prime, mais pour rester équitable il faudrait alors améliorer le programme NumWorks de façon similaire.

Après, cela n'enlève rien au fait que la HP Prime reste il me semble plus rapide que les TI-Nspire et Casio fx-CP400, ses concurrentes 'naturelles', même si dans le contexte de sorties graphiques il n'était pas possible ici de faire un test équitable avec les TI-Nspire. On aurait pu le porter pour Casio fx-CP400 par contre, mais quel intérêt ? :p
C'est juste qu'il sera désormais faux de continuer à poster partout que la HP Prime est la calculatrice la plus rapide.

Re: Performances, la NumWorks détrône la HP Prime ! :o

Unread postPosted: 10 Dec 2017, 13:42
by parisse
Il n'y a pas de contestation sur ce point, des qu'on fait uniquement des operations de base sur les flottants (et a fortiori sur les complexe flottants), l'interpreteur Python est plus rapide, il a ete concu pour ca et il est plus optimise, et de toutes facons l'interpreteur CAS est intrinsequement plus lent (par exemple pour creer un complexe il fait une allocation memoire, c'est le prix a payer pour avoir certaines fonctionnalites comme par exemple i^2 est -1 alors qu'en Python 1_j^2 est -1+0j).
Le point est que ca n'est pas important: dans un contexte d'enseignement au lycee, tous les interpreteurs seront suffisamment rapides, dans un autre contexte si ce sont les performances de l'interpreteur lui-meme qui dominent, c'est que le langage n'est pas le bon. Si vous commencez a faire de l'arithmetique par exemple et que vous visez un programme performant, ce qui comptera le plus ce ne sera pas la vitesse de l'interpreteur lui-meme, mais la vitesse de la commande de puissance modulaire rapide ou du test de primalite ou de l'algorithme de factorisation d'entiers... Ou si vous faites des simulations, ce qui importera ce sera la performance des instructions agissant sur des listes ou vecteurs qui regroupent plusieurs experiences.
Ceci etant dit, je n'ai rien contre ameliorer les performances de l'interpreteur de Xcas, il faut simplement garder en tete que ca restera intrinsequement plus lent que du Python, qui lui-meme est plus lent que javascript sur du code compile avec emscripten, sans que ca ait la moindre influence sur le choix du langage au lycee.