Journal avec Pythran, Numpy file comme le vent

46
5
avr.
2013

Salut mon petit journal,

je te tiens de temps en temps au courant des avancement de Pythran, ze convertisseur Python -> C++ dédié au calcul scientifique. La dernière fois que nous avons discuté, tu m'avais dit de repasser te voir quand je serais capable de supporter ce genre de calculs:

import numpy as np
n = 100000
b, c = np.ones(n), np.ones(n)
d = np.sqrt(b*b+c*c)

intéressé que tu étais de savoir le gain en vitesse atteignable. C'est chose faite. Le support est loin d'être total et se trouve dans la branche numpy du git.

Quelques résultats préliminaires donc, sur un quadcore i7 hyperthreadé.

>>> %timeit np.sqrt(b*b+c*c)
100 loops, best of 3: 2.59 ms per loop

Puis avec numexpr:

>>> %timeit numexpr.evaluate("sqrt(b*b+c*c)")
1000 loops, best of 3: 728 us per loop

Et enfin avec Pythran (Advanced_Vector_Extensions et Openmp et Expression_templates inside):

>>> %timeit my.pythranized(b,c)
1000 loops, best of 3: 276 us per loop

Comme ça doit te laisser rêveur, je te dis bonne nuit, et continue à faire de beaux rêves pythranesques !

  • # Toujours intéressant

    Posté par (page perso) . Évalué à 10.

    J'ai pas grand chose à dire, mais je trouve triste que ce journal ait 0 commentaire, parce que j'apprécie le travail. J'aurai probablement une utilité pour Pythran dans quelques mois et je garde un oeil dessus.

    Bon boulot donc !

    • [^] # Re: Toujours intéressant

      Posté par (page perso) . Évalué à 4.

      Je suis également surpris du manque de commentaires. Je n'en ai pas l'utilité pour l'instant, mais bossant pas mal avec Python sur différents projets, c'est une des options que je garde en tête (avec numpy et cython) en cas de vrai besoin de performances.

    • [^] # Re: Toujours intéressant

      Posté par (page perso) . Évalué à 3.

      Je vais faire une confidence : je ne comprends pas les infos données à propos de performance.

      Commentaire sous licence LPRAB - http://sam.zoy.org/lprab/

      • [^] # Re: Toujours intéressant

        Posté par . Évalué à 1.

        Tout pareil : des temps sans comparaison avec ce que font d'autres (comme du C++ pur, puisqu'il s'agit là d'un convertisseur Python -> C++) ne me parait pas parlant, pour quelqu'un (comme moi) qui ne baigne pas dedans…

        • [^] # Re: Toujours intéressant

          Posté par (page perso) . Évalué à 6.

          Tu veux dire que les trois liens Wikipedia n'aident pas ?

          Si je te dis que numpy crée un tableau temporaire par opération, tu imagines le surcoût en:

          • allocation mémoire / parcours de tableau (prix des accès mémoires)
          • coût de contrôle (prix de l'itération)

          en plus la vectorisation (i.e. faire 4 sommes en une opération vectorielle) n'aide pas car on se paie 1 chargement mémoire, 1 opération, 1 déchargement mémoire.

          Pythran fusionne les boucles, ce qui augmente l'intensité de calcul (on charge une fois les opérandes, on calcule beaucoup dessus, on décharge le résultat) et permet d'avoir un gros bénéfice lié à la vectorisation.

          La parallélisation de la boucle englobante vient ajouter au tout.

          Pas de comparaison tu dis ? Et la comparaison avec numexpr, hein ? Pour comparer au C++, forcément si le dev connait et applique les techniques sus-citées, il ira au moins aussi vite. Mais ça lui prendra pas trois lignes de code… Par contre une comparaison à numpypy et numba s'impose en effet :-)

          voili voilou, j'espère avoir mieux argumenté là !

        • [^] # Re: Toujours intéressant

          Posté par . Évalué à 6.

          des temps sans comparaison avec ce que font d'autres (comme du C++ pur, puisqu'il s'agit là d'un convertisseur Python -> C++)

          Je ne crois pas que la comparaison avec du C++ direct soit pertinente. Pytrans se pose pas en concurrent du C du C++ ou autre, mais plutôt comme une solution d'optimisation du python donc à mon humble avis c'est plus avec les autres techniques de python qu'il doit être comparé (pypy entre autre).

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

          • [^] # Re: Toujours intéressant

            Posté par (page perso) . Évalué à 5.

            Au contraire : C/C++ a de meilleures performances en général. C'est pertinent de montrer à la fois par rapport aux concurrents, mais aussi par rapport au Saint Graal du code qui s'exécute rapidement.

            Par contre, associer les chiffres avec des pourcentages auraient peut-être aidé à comprendre les résultats ?

            Commentaire sous licence LPRAB - http://sam.zoy.org/lprab/

            • [^] # Re: Toujours intéressant

              Posté par . Évalué à 6.

              Au contraire : C/C++ a de meilleures performances en général. C'est pertinent de montrer à la fois par rapport aux concurrents, mais aussi par rapport au Saint Graal du code qui s'exécute rapidement.

              Ben la différence avec du C++ c'est :

              • overhead du à la machinerie python/C++
              • les techniques éventuelles que pytrans n'utilisent pas

              Le premier est lié à l'interpréteur utilisé (il ne peut pas y changer grand chose), le second, ben c'est pour ça qu'à chaque fois il nous explique les techniques ou techno qu'il met en œuvre (openmp par exemple).

              Par contre, associer les chiffres avec des pourcentages auraient peut-être aidé à comprendre les résultats ?

              Grosso modo dans son petit test il est 10 fois plus rapide que cpython/numpy et 3 fois plus que numexpr, mais ce n'est pas un vrai benchmark de la vraie vie. il voulait juste montrer qu'il a implémenté une fonctionnalité qui a était demandé dans le précédent journal.

              Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

            • [^] # Re: Toujours intéressant

              Posté par (page perso) . Évalué à 3.

              Même si je doute de la pertinence de la comparaison, j'ai demandé à un étudiant de coder l'algo décrit ci-dessue n C++ avec de l'OpenMP. Ça donne ça :

                  struct timeval start, stop;
                  gettimeofday(&start,0);
                  double h[10000];
                  std::fill(h, h+10000, 1);
                  double k[10000];
                  std::fill(k, k+10000, 1);
                  double l[10000];
              
              #pragma omp parallel for
                  for(int i=0; i<10000; i++)
                      l[i] = std::sqrt(h[i] * h[i] + k[i] * k[i]);
              
                  gettimeofday(&stop,0);
                  std::cout << (stop.tv_usec - start.tv_usec) << "micro sec" << std::endl;
              
              

              ce qui me parait raisonnable.

              $> make CXXFLAGS='-O3 -march=native' test
              $> ./test # j'ai fait la médiane sur 100 runs
              486micro sec
              
              

              Ce qu'on peut lire comme : pas mal, mais g++-4.7 ne vectorise pas la boucle mesurée (j'ai vérifié)et nous on utilise des infos de haut niveau pour le faire, donc… on lui colle la vectorisation dans les dents.

              • [^] # Re: Toujours intéressant

                Posté par . Évalué à 5.

                Sur un cas comme celui-ci précisément, je pense qu'avec eigen ça doit carburer comme il faut (autant pour avoir un code de plus haut niveau que pour les performances). Par contre le temps de compilation grimpe (mais on compile moins de fois qu'on exécute le code en principe.

                Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Re: Toujours intéressant

          Posté par (page perso) . Évalué à -1.

          Ce qui serait pertinent, c'est de comparer avec le C++, mais à la fois les performances et le temps de développement.

          En général, quand on code en Python, c'est que soit les perfs ne sont pas importantes, soit on n'a pas le temps de faire une vraie version optimisée aux petits oignons avec du C/C++.

          • [^] # Re: Toujours intéressant

            Posté par . Évalué à 2.

            il ne faut pas oublié que (pour le moment ?) c'est du développement contraint (par exemple tu ne peux pas créer tes propres classes). Il s'agit plutôt d'optimiser un programme python déjà existant (la bonne vielle règle des 20% de code qui consomment 80% du temps d’exécution).

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Toujours intéressant

      Posté par . Évalué à 1.

      Effectivement ca a l'air interessant. Faudra qu'à l'okkaz j'essaye, même si je continue à faire du traitement de donnée en C++, ça fait un moment que j'hésite à passer à python (premièrement c'est plus lent, ensuite c'est pas mal de travail de changer de language alors que parfois il me suffit de copier-coller un bout de vieux code tout moche pour faire ce que je veux)

    • [^] # Re: Toujours intéressant

      Posté par (page perso) . Évalué à 1.

      Merci! Hésite pas à passer sur freenode #pythran pour nous donner des bouts de code, on en cherche !

  • # Impressionnant

    Posté par . Évalué à 4.

    Quand je vois des performances pareilles pour très peu d'intervention manuelle, je dis bravo, surtout par rapport à cython qui nécessite de typer à peu près tout et donc de casser la compatibilité source.

    Tu dis que le support de numpy est loin d'être total, que manque-t-il actuellement?

  • # Et avec des nombres aléatoires…

    Posté par (page perso) . Évalué à 4.

    Est-ce que ça donne le même genre de résultat ?

  • # PyTables

    Posté par . Évalué à 1.

    Salut,

    numexpr est compris dans pytables, cela permet d'avoir des résultats vraiment intéressant car c'est plutôt orienté sur l'aspect optimisation de la mémoire. Penses tu qu'il sera possible à terme de pouvoir utiliser les outils de pytables avec pythran.

  • # Liens pas très utiles en l'état

    Posté par . Évalué à 0.

    J'ai bien l'impression que les trois liens Wikipedia pointent vers des pages qui n'existent pas…

    Cela dit, les perfs ont l'air vraiment intéressantes, j'utilise python pour faire du calcul assez régulièrement (non ! pas taper !), je vais voir ce que ça donne.

    from __future__ import division

    • [^] # Re: Liens pas très utiles en l'état

      Posté par . Évalué à 2.

      Ça doit venir de l'interprétation des liens Wikipédia qui fait pointer vers le Wikipédia français.
      Ça marchait il y a quelques jours, c'est peut-être un bug du site.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.