• # Aie mes yeux...

    Posté par  . Évalué à 10 (+10/-0).

    J'ai voulu lire le code C++… Ça pique. C'est illisible, et pas a cause d'optimisations.
    Ce qui, en revanche, n'est pas le cas du code nim, étrangement…

    Pour info, le fichier .cpp à 103 lignes, le fichier .nim 335, alors que C++ est réputé verbeux.

    Là ou le code Nim est bien lisible: une instruction par ligne, des lignes vides pour aider l'oeil a distinguer les blocs, des commentaires qui sont sur leur propre ligne, du code aligné… le C++ à l'air obfusqué et codé dans du pré-C++11.
    D'ailleurs, aucune bibliothèque de C++ n'est utilisée ici. Pourquoi? Ça aurait réduit considérablement la quantité de code à écrire… et aurait pu inclure du code optimisé, justement.
    Perso, quand je dois faire de la 3D, je n'implémente pas mes algo de détection, j'utilise ce qui existe. Que l'on compare son implémentation de nim avec du code C++ qui utilise ça, et on en reparle.

    Le code me semble clairement écrit en faveur de nim, et le C++ semble malgré tout proche de nim question performances. Ma conclusion c'est que Nim est plus lent que C++, et le code est fait salement en C++ pour empêcher de facilement voir pourquoi c'est lent.
    Non, ce n'est pas du C++ naïf, sinon l'auteur n'utiliserais inline, qui n'est pas ce que l'on trouve en 1er dans les tutoriels et docs.

    Extraits choisis de code C++:

         if (det<0) return 0; else det=sqrt(det);
        return (t=b-det)>eps ? t : ((t=b+det)>eps ? t : 0);

    Pourquoi laisser le else? Si tu retournes dans le if, le else sert évidemment à rien.
    2 branchements avec l'opérateur ternaire sur un return? J'appelle ça du code de merde, sans parler des affectations au milieu: l'auteur ne veut pas que l'on puisse comprendre ce qui se fait.

      inline bool intersect(const Ray &r, double &t, int &id){
      double n=sizeof(spheres)/sizeof(Sphere), d, inf=t=1e20;
      for(int i=int(n);i--;) if((d=spheres[i].intersect(r))&&d<t){t=d;id=i;}
      return t<inf;
    }

    Errrr…. spheres était un table de taille de fixe, on peut constater ici plusieurs erreurs, possiblement optimisée par le compilo, mais peut-être pas:

    • a chaque appel de la fonction intersect, on refait une division inutile: n devrais être une constante, calculé une seule fois. Et pas un double.
    • cast double vers int inutile pour n.
    • for(int…) vraiment? Même en C ou C++03 on faisait mieux, avec les pointeurs. Du C++11 moderne, donc de moins de 10 ans, utiliserais juste un range for. Bon, ici, il semble réutiliser l'entier pour le retourner dans le cas ou il trouve une intersection, mais vu que le code est imbuvable, difficile de dire si on ne peut pas s'en passer.

    Aussi:

    Nim 1.2.0 (GCC 10.1), flag -d:danger

    Donc, version récente: "1.2.0 2020-04-03".

    Pourtant, il n'utilise pas C++20, pourquoi? Ça aurait permis d'éviter certaines implémentations, genre clamp vs std::clamp.

    • [^] # Re: Aie mes yeux...

      Posté par  . Évalué à 5 (+4/-1).

      Ne te fatigue pas. Les bench entre langages n'ont aucun intérêt sauf dans un cas : quand on explique ce que l'on bench. Si le bench était là pour vérifier l'impact d'une ou d'une série d'optimisation de nim, précises et décrites. Alors ça aurait un intérêt. Dans presque tous les autres cas ça n'a pas le moindre intérêt. Là il ne s'agit que de faire un peu de pub à Nim.

      En soit pourquoi pas, mais c'est fait sans vraiment de rigueur.

      • [^] # Re: Aie mes yeux...

        Posté par  . Évalué à 5 (+4/-1).

        Là il ne s'agit que de faire un peu de pub à Nim.

        Désolé, j'aime pas quand on tape injustement sur un langage en faisant exprès de coder avec les pieds pour faire passer un autre langage comme "plus rapide".

        Au moins avoir un code lisible dans les 2 comparaisons et utiliser des technologies de même génération, ça me semble un minimum requis de bonne fois.

        • [^] # Re: Aie mes yeux...

          Posté par  . Évalué à 5 (+4/-1).

          Je n'ai pas dis que c'était bien. Je dis que la démarche initiale est mauvaise quelque soit le code que tu met en face. Il n'y a pas besoin d'aller voir le code ni de connaître l'un ou l'autre des langages pour comprendre le manque d'honnêteté.

          Un bench sans explication précise de la différence → démarche malhonnête. Il y a bien trop d'articles de ce genre pour s'appesantir. Déjà que ce niveau de gain de performance est ridicule pour la majorité des usage.

          • [^] # Re: Aie mes yeux...

            Posté par  . Évalué à 1 (+0/-1). Dernière modification le 02/08/20 à 23:02.

            Vrai aussi. Mais je préférais aller vérifier avant de moinsser :)

          • [^] # Re: Aie mes yeux...

            Posté par  . Évalué à 3 (+3/-0).

            Je n'ai pas dis que c'était bien. Je dis que la démarche initiale est mauvaise quelque soit le code que tu met en face. Il n'y a pas besoin d'aller voir le code ni de connaître l'un ou l'autre des langages pour comprendre le manque d'honnêteté.

            Un bench sans explication précise de la différence → démarche malhonnête. Il y a bien trop d'articles de ce genre pour s'appesantir. Déjà que ce niveau de gain de performance est ridicule pour la majorité des usage.

            J'ai porté le code C++ ligne par ligne en Nim, en séparant les lignes qui étaient trop code-golfer en plusieurs.
            Je vais même jusqu'à utiliser le même générateur de nombre aléatoire.
            Les images générées sont absolument identiques pour les mêmes paramètres d'entrées.

            Quelle partie de ma démarche est mauvaise? Où est le manque d’honnêteté?

            Le bench est juste la première partie de l'article, le reste de l'article est à propos des fonctionnalités pour écrire du code correct:
            - représentation d'unités physiques et concordance des unités vérifiée par le compilateur.
            - traçage de la mutabilité
            - traçage des effets secondaires
            de la vitesse de compilation et de l'intéropérabilité avec C ou C++

            Ce que je vois surtout ici c'est une attaque sans raison "qui manque d’honnêteté", à part clarifier que tu n'as pas lu le code et que tu pars d'un biais négatif de base.

            • [^] # Re: Aie mes yeux...

              Posté par  . Évalué à 2 (+0/-0).

              Salut,

              C'est cool de venir répondre.

              Quelle partie de ma démarche est mauvaise?

              En fait il n'y a pas grand chose à tirer d'un benchmark qui ne donne qu'une valeur (ou un moyenne sur plusieurs lancements). Est-ce que ça vient d'un overhead initial qui est constant ? Vu comme les résultats sont proches (je suis même pas certains qu'on ne soit pas dans la variance) il est possible que le moindre changement de paramètre donne un effet dans un sens ou un autre. Du coup je ne vois pas trop qu'est-ce que l'on peut tirer de ce bench.

              Le bench est juste la première partie de l'article

              Tout à fait et c'est intéressant, mais le fais d'avoir mis en avant la partie bench + le titre qui a était donné ici (je sais que ce n'est pas de toi) m'a fait un peu sur-réagir. Mais je maintiens que le bench est loin de donner suffisamment d'informations (la variance des run, faire varier les entrées, voir expliquer l'enjeux du bench,…) pour être utile.

              Ce que je vois surtout ici c'est une attaque sans raison "qui manque d’honnêteté", à part clarifier que tu n'as pas lu le code et que tu pars d'un biais négatif de base.

              Avant de lire un livre j'en lis la préface :)
              Sincèrement la seconde partie m'a vraiment intéressée, c'est juste le bench qui en soit ne donne pas assez d'info que je lise ou non le code n'y changera rien.

              Je suis désolé d'avoir parler d’honnêteté intellectuelle. Mes mots ont largement dépassés mes pensées.

              • [^] # Re: Aie mes yeux...

                Posté par  . Évalué à 1 (+1/-0).

                En fait il n'y a pas grand chose à tirer d'un benchmark qui ne donne qu'une valeur (ou un moyenne sur plusieurs lancements). Est-ce que ça vient d'un overhead initial qui est constant ? Vu comme les résultats sont proches (je suis même pas certains qu'on ne soit pas dans la variance) il est possible que le moindre changement de paramètre donne un effet dans un sens ou un autre. Du coup je ne vois pas trop qu'est-ce que l'on peut tirer de ce bench.

                C'est justement ce qui est intéressant, si je présentais l'article sans le benchmark, le reproche serait "Mais quid de la performance, est-ce que Nim joue dans la même classe que C ou C++?". Ce benchmark le prouve, le code Nim ou C ou C++ ont le même ordre de grandeur en performance. J'irai même plus loin, "toute performance atteignable en C est également atteignable en Nim". Maintenant + ou - 2% ne va pas changer la donne pour la majorité des gens, c'est là où la deuxième partie intervient.

                Sincèrement la seconde partie m'a vraiment intéressée, c'est juste le bench qui en soit ne donne pas assez d'info que je lise ou non le code n'y changera rien.

                Le but du bench à la base est de valider que ma librairie de parallélisme Weave scale a minima comme OpenMP. Étant donné l'implémentation, je suis en fait étonné qu'il y ait une différence de plus de 1% en single-threaded entre le code C++ ou Nim. Je ne m'apesantis pas dessus justement parce que la présentation du bench avait pour but de régler le sort de "l'éléphant" pour tout nouveau langage (plus rapide que C?) et ensuite passer dans le vif du sujet, les fonctionnalités uniques.

                Je fournis plus d'analyse sur la partie multithreadée du bench ici https://github.com/mratsim/weave/tree/master/demos/raytracing.
                Le bench single-threadé est pour moi une baseline (i.e. s'il y a un écart important mon code est buggué) mais utilisée ici pour rassurer quant à la performance, les personnes familières avec Nim savent que porter 1->1 du code C ou C++ (sans inheritance) en Nim donne les mêmes performances peu ou prou quelques pourcents.

                • [^] # Re: Aie mes yeux...

                  Posté par  . Évalué à 2 (+0/-0).

                  C'est justement ce qui est intéressant, si je présentais l'article sans le benchmark, le reproche serait "Mais quid de la performance, est-ce que Nim joue dans la même classe que C ou C++?".

                  Je comprends, ça n'aurait pas était mon cas donc je ne l'ai pas vu comme ça.

                  Le but du bench à la base est de valider que ma librairie de parallélisme Weave scale a minima comme OpenMP.

                  Je comprends, c'est tellement peu dis que je ne l'ai pas intégré.

                  Je fournis plus d'analyse sur la partie multithreadée du bench ici https://github.com/mratsim/weave/tree/master/demos/raytracing.

                  Ah oui c'est plus complet :)

                  Le bench single-threadé est pour moi une baseline (i.e. s'il y a un écart important mon code est buggué) mais utilisée ici pour rassurer quant à la performance, les personnes familières avec Nim savent que porter 1->1 du code C ou C++ (sans inheritance) en Nim donne les mêmes performances peu ou prou quelques pourcents.

                  D'acc je comprends la démarche

        • [^] # Re: Aie mes yeux...

          Posté par  . Évalué à 3 (+3/-0).

          Désolé, j'aime pas quand on tape injustement sur un langage en faisant exprès de coder avec les pieds pour faire passer un autre langage comme "plus rapide".

          C'est exactement le même code que celui utilisé dans Phoronix ou par l'auteur originel. Le code Nim est une traduction 1-1. Les deux ont été comparé avec le même compilateur (GCC 10.1).

          Je ne crois pas avoir tapé sur C++ dans l'article non plus.

      • [^] # Re: Aie mes yeux...

        Posté par  (site Web personnel) . Évalué à 2 (+0/-0).

        Au moins, ça donne des ordres de grandeur ; soyons optimistes !

      • [^] # Re: Aie mes yeux...

        Posté par  . Évalué à 2 (+2/-0).

        Le code Nim est un port 1-1 du code C++.

        Le bench est là pour vérifier la parallélisation OpenMP vs Weave, ma librairie de parallélism en Nim.

        Le bench n'est qu'une partie de l'article, l'analyse complète des performances est ici: https://github.com/mratsim/weave/tree/master/demos/raytracing#results--analysis

    • [^] # Re: Aie mes yeux...

      Posté par  . Évalué à 4 (+1/-0).

      Question bête si le cpp fait 100 lignes, est-ce que tu pourrais le réécrire à la sauce C++ moderne ? au moins la comparaison serait plus juste.

      "La première sécurité est la liberté"

      • [^] # Re: Aie mes yeux...

        Posté par  . Évalué à 4 (+3/-1).

        Quel est l'intérêt ? Un benchmark devrait être là pour répondre à une hypothèse.

        La démarche peut être de prendre le même algo est de l'écrire dans les 2 langages. Plus que les langages1 tu compare les compilateurs. Mais pour que ça ai un intérêt il faut ensuite faire le travail d'analyse des résultats (quels optimisations ont jouées dans un sens comme dans l'autre ?). Sinon ça n'apporte rien et tu ne pourra pas en déduire que l'un est plus performant que l'autre. Juste que dans un contexte donné, il est arrivé que l'un soit plus rapide que l'autre.

        C'est pour ça que ce genre de papier ne sont là que pour générer de la visibilité et tenter de créer une hype.


        1. pas totalement vrai car selon la sémantique des langages il est possible pour le compilateur d'émettre certaines hypothèses ou pas 

        • [^] # Re: Aie mes yeux...

          Posté par  . Évalué à 3 (+0/-0).

          Ce n'est pas parce que le benchmark est compliqué, que son résultat n'est pas intéressant.

          "La première sécurité est la liberté"

          • [^] # Re: Aie mes yeux...

            Posté par  . Évalué à 3 (+2/-1).

            Ah non ce n'est pas une question de complexité, mais d'information qu'il apporte. Si tu ne peux pas conclure mieux que « ce snippet de code est plus performant actuellement que celui-ci » alors l'effort ne t'apporte rien. Le plus difficile dans un benchmark ce n'est pas d'écrire du code, c'est de faire quelque chose de tes résultats, de pouvoir comprendre la différence et d'où elle vient.

            Pour voir quelque chose de bien fait c'est simple, on peut regarder les journaux sur pythran où c'est l'inverse ou tu peut regarder les bench du noyau où les dev prennent le noyau avec et sans leur feature et montrent l'impact du code qu'ils ont produit. C'est à ça que ça sert un bench. Les concours de phallus c'est de l'énergie perdu pour rien.

            • [^] # Re: Aie mes yeux...

              Posté par  . Évalué à 4 (+1/-0).

              Si l'algorithme est le même entre 2 logiciels, on peut conclure que pour ce logiciel, le code est plus ou moins compact, rapide, expressif, etc…

              C'est peu le jeu de https://benchmarksgame-team.pages.debian.net/benchmarksgame/

              "La première sécurité est la liberté"

              • [^] # Re: Aie mes yeux...

                Posté par  . Évalué à 2 (+0/-0). Dernière modification le 03/08/20 à 16:54.

                Si l'algorithme est le même entre 2 logiciels, on peut conclure que pour ce logiciel, le code est plus ou moins compact, rapide, expressif, etc…

                Ça c'est pas du bench :) La seconde partie de l'article est intéressante de ce point de vu à ce titre.

                Et pour la vitesse ça te dis que cette implémentation de l'algo dans tel langage est plus rapide que l'implémentation de l'autre. Si tu as besoin de cette implémentation de l'algo, ça doit être utile ^^

                • [^] # Re: Aie mes yeux...

                  Posté par  . Évalué à 3 (+0/-0).

                  On peut dire qu'il y a 2 type d'algo ce qui manipule des symboles (AST, …) et ceux qui manipulent des nombres (accéléré par SIMD et souvent openmp,…).

                  Peut-on imaginer un algo numérique de l'ensemble des algo numériques qui soit 3x plus rapide dans un langage A par rapport à B, mais qui serait 2x plus lent pour tous les autres en moyenne ?

                  Je parle bien sûr sans "triche".

                  "La première sécurité est la liberté"

                  • [^] # Re: Aie mes yeux...

                    Posté par  . Évalué à 2 (+0/-0).

                    Quand tu es CPU bound, tu as une part de ta performance qui vient de ton algo (ne pas refaire des calcul n fois comme le décrit freem) et une autre part qui va être très pointue les différentes formes de parallélisation, la manipulation des registres, l'utilisation des extensions que te proposent ou non ton CPU,…

                    Peut-on imaginer un algo numérique de l'ensemble des algo numériques qui soit 3x plus rapide dans un langage A par rapport à B, mais qui serait 2x plus lent pour tous les autres en moyenne ?

                    Tu établi comment que tes algos sont au niveau à l'état de l'art ? Que cette implémentation du ray tracing ne tire pas particulièrement parti d'une opti qui est plus anodine généralement ? Même sans pointer une malfaçon, on tombe facilement dans les biais. Rien que l'expertise que tu as ou pas sur un langage et son écosystème peut avoir des conséquences (ne pas utiliser la bonne implémentation de ta structure de données par exemple).

                    En plus là il n'est pas question de tel rapport de différence. Deux versions de compilateurs donnent plus de différence que ce qu'il y a entre nim et c++.

                    • [^] # Re: Aie mes yeux...

                      Posté par  . Évalué à 2 (+0/-1).

                      Tu établi comment que tes algos sont au niveau à l'état de l'art ?

                      Qu'est-ce que cela peut faire si on compare 2 implémentations ?

                      Rien que l'expertise que tu as ou pas sur un langage et son écosystème peut avoir des conséquences

                      ça c'est évident. C'est l’intérêt du benchmark game que chaque fan boy puisse développer pour son propre langage préféré.

                      Tu confirmes donc bien que si 2 personnes du même niveau d'expertise implémente le même algo avec un minimum de complexité, on peut comparer la vitesse du langage(compilo + puissance de la sémantique du langage).

                      "La première sécurité est la liberté"

                      • [^] # Re: Aie mes yeux...

                        Posté par  . Évalué à 3 (+1/-0).

                        C'est l’intérêt du benchmark game que chaque fan boy puisse développer pour son propre langage préféré.

                        Il faut que le bench soit vraiment établi pour ça mais bon…

                        Tu confirmes donc bien que si 2 personnes du même niveau d'expertise […]

                        Non à l'état de l'art. Sinon tu risque de juste comparer la simplicité des langages.

                        […] avec un minimum de complexité, on peut comparer la vitesse du langage

                        Non, tu compare 2 implémentations données, sur une machine donnée, à un moment donné sur un test donné.

                        Et attention ! Tu gagne 3.7s, on ne sait pas comment évolue cette valeur par rapport aux paramètres du test.

                        • [^] # Re: Aie mes yeux...

                          Posté par  . Évalué à 3 (+0/-0).

                          Non, tu compare 2 implémentations données, sur une machine donnée, à un moment donné sur un test donné.

                          C'est toujours le cas pour tout test de performance ! C'est pour ça que les conditions du tests sont donnés, pour être reproduit.

                          "La première sécurité est la liberté"

                          • [^] # Re: Aie mes yeux...

                            Posté par  . Évalué à 2 (+0/-0).

                            Donc à partir d'un point précis, tu pense que l'on peut faire une déduction sur des langages ? S'il n'y a pas d'hypothèses posée avant, alors ton hypothèse c'est le test. En quoi ce test là plutôt qu'un autre ? Quels sont ses propriétés ? Pourquoi choisir ses paramètres (surtout quand on ne les fais pas varier) ?

                            Donc on prend 2 bout de code, dont rien indique l'effort qui a était fait pour qu'ils soient pertinents. On les a lancé et on a ni hypothèses initiales qui cherchée à être vérifiée, ni conclusion qui tentent d'expliquer les résultats.

                            • [^] # Re: Aie mes yeux...

                              Posté par  . Évalué à 3 (+0/-0).

                              C'est vrai que pour le benchmark game, il y a une dizaine de benchmark, justement pour éviter le problème que tu évoques. L'auteur de Nim devrait y participer d'ailleurs.

                              Je croyais que tu soutenais que c'était impossible de comparer des langages informatiques au niveau efficacité. Je sais que c'est complexe, mais pas impossible.

                              "La première sécurité est la liberté"

                              • [^] # Re: Aie mes yeux...

                                Posté par  . Évalué à 2 (+0/-0).

                                Je croyais que tu soutenais que c'était impossible de comparer des langages informatiques au niveau efficacité. Je sais que c'est complexe, mais pas impossible.

                                Désolé je n'ai pas était très clair et même certains raccourcis font penser ça. Non c'est "juste" que le bench devrait être là pour appuyer une hypothèse ou être expliqué par une hypothèse.

                                C'est véritablement compliqué de faire un bench et l'auteur de celui-ci a fait un travail (tester plusieurs compilateurs, donner une description de la machine sur le quel il a fait son test, donner les sources du test,…) mais ce n'est pas plus que de l'amusement perso (ce qui est très bien !).

                                • [^] # Re: Aie mes yeux...

                                  Posté par  . Évalué à 1 (+1/-0).

                                  C'est véritablement compliqué de faire un bench et l'auteur de celui-ci a fait un travail (tester plusieurs compilateurs, donner une description de la machine sur le quel il a fait son test, donner les sources du test,…) mais ce n'est pas plus que de l'amusement perso (ce qui est très bien !).

                                  Le code C++ et Nim sont équivalent, l'algo a été porté 1-1.

                                  Le but initial du benchmark est de comparer la parallélisation OpenMP contre ma propre librairie Weave https://github.com/mratsim/weave/tree/master/demos/raytracing#results--analysis

                                  L'idée est d'avoir un bench complètement compute-bound (et non pas memory-bound comme la multiplication de matrice) pour vérifier si j'ai bien un speed-up de 18x sur ma machine avec 18 coeurs.

                                  En réalité j'ai entre 20x et 21.8x ce qui doit s'expliquer par l'hyperthreading.

                                  • [^] # Re: Aie mes yeux...

                                    Posté par  . Évalué à 2 (+0/-0).

                                    L'idée est d'avoir un bench complètement compute-bound (et non pas memory-bound comme la multiplication de matrice) pour vérifier si j'ai bien un speed-up de 18x sur ma machine avec 18 coeurs.

                                    En relisant 2 fois l'article (une fois en diagonale et une seconde fois plus attentivement), j'ai retrouvé la mention. C'est dommage de ne pas l'avoir plus mis en avant.

                                    • [^] # Re: Aie mes yeux...

                                      Posté par  . Évalué à 1 (+1/-0).

                                      Etant donné que la plupart de mes posts dans la communauté Nim était à propos de comment maximiser ses performances je voulais mettre en avant autre chose pour une fois et avoir la perf que comme une mise en bouche :/.

      • [^] # Re: Aie mes yeux...

        Posté par  . Évalué à 3 (+2/-1).

        Bah, déjà, je pourrais le rendre moins pire en mettant un simple coup d'astyle. C'est bien pour ça que je dis que c'est fait exprès: un logiciel peut rendre ce code moins illisible.

        Et, ça restera toujours du code pré 2011. Après, oui, je pourrais probablement le réécrire. Sauf que bon, je ne suis pas mathématicien. Certes, avec des outils comme valgrind et google-perftools, je pourrais trouver les parties à optimiser… mais, au final, ça avancerais à quoi?
        Mes projets perso du moment, c'est:

        • patcher coco/R pour qu'il être interactif: pour l'instant c'est juste un générateur de compilateurs… je voudrais m'en servir pour en faire un interpréteur de commandes;
        • utiliser ce patch pour écrire un langage (yep) qui remplacera (au moins dans mes usages) la commande dialog, le tout sur une logique client-serveur;
        • diverses autres bricoles;

        Je peux bien glandouiller un peu ici, et dénoncer grave un pseudo article (et tant pis pour stressand) sans pour autant me détourner de mes objectifs?

        • [^] # Re: Aie mes yeux...

          Posté par  . Évalué à 1 (+2/-3). Dernière modification le 03/08/20 à 22:35.

          Je peux bien glandouiller un peu ici, et dénoncer grave un pseudo article (et tant pis pour stressand) sans pour autant me détourner de mes objectifs?

          Bien sur, tu peux te limiter à dénoncer et paraître pour un vieux troll grincheux alors que tu peux aller jusqu'à prouver qu'il a tord et en sortir comme le sauveur qui aura rétabli la vérité.

          /me lance les dés

    • [^] # Re: Aie mes yeux...

      Posté par  . Évalué à 2 (+3/-1).

      Hello, je suis l'auteur de l'article, il semble qu'il y ait une énorme mécompréhension, de l'article comme des codes C++ et Nim.

      J'ai voulu lire le code C++… Ça pique. C'est illisible, et pas a cause d'optimisations.
      Ce qui, en revanche, n'est pas le cas du code nim, étrangement…

      Pour info, le fichier .cpp à 103 lignes, le fichier .nim 335, alors que C++ est réputé verbeux.

      Là ou le code Nim est bien lisible: une instruction par ligne, des lignes vides pour aider l'oeil a distinguer les blocs, des commentaires qui sont sur leur propre ligne, du code aligné… le C++ à l'air obfusqué et codé dans du pré-C++11.
      D'ailleurs, aucune bibliothèque de C++ n'est utilisée ici. Pourquoi? Ça aurait réduit considérablement la quantité de code à écrire… et aurait pu inclure du code optimisé, justement.
      Perso, quand je dois faire de la 3D, je n'implémente pas mes algo de détection, j'utilise ce qui existe. Que l'on compare son implémentation de nim avec du code C++ qui utilise ça, et on en reparle.

      Le code me semble clairement écrit en faveur de nim, et le C++ semble malgré tout proche de nim question performances. Ma conclusion c'est que Nim est plus lent que C++, et le code est fait salement en C++ pour empêcher de facilement voir pourquoi c'est lent.
      Non, ce n'est pas du C++ naïf, sinon l'auteur n'utiliserais inline, qui n'est pas ce que l'on trouve en 1er dans les tutoriels et docs.

      Le code C++ est connu et utilisé dans un certain nombre de benchmarks, comme Phoronix https://openbenchmarking.org/test/pts/smallpt.
      Le code a pour but de démontrer qu'écrire un RayTracer basique mais avec des fonctionnalités intéressantes (Monte-Carlo + Interruption via roulette russe par exemple) ne demande pas des milliers de lignes. De fait il a été code-golfé en 100 lignes. Voir: http://www.kevinbeason.com/smallpt/

      Concernant GLM, ça ne remplace que 10 lignes du code C++ et surtout c'est contre la philosophie originale du code, qui est d’être sans dépendance.

      Le code Nim est un port 1->1 du code C++, le code-golfing en moins, les commentaires ont été ajoutés parce que le code C++ était difficile à lire.

      Le code C++ n'est pas fait salement pour obfuscation mais pour tenir en moins de 100 lignes, le code Nim reproduit fidèlement le code C++ et les deux codes produisent exactement les mêmes images avec les mêmes paramètres. Je suis même allé jusqu'à comparer le contenu des variables lignes par lignes lorsque je détectais des écarts.

      De fait, si le code C++ était intentionnellement lent (ce qui est complètement faux), le code Nim reproduirait cette lenteur.

      Extraits choisis de code C++:

          if (det<0) return 0; else det=sqrt(det);
         return (t=b-det)>eps ? t : ((t=b+det)>eps ? t : 0);
      

      Pourquoi laisser le else? Si tu retournes dans le if, le else sert évidemment à rien.
      2 branchements avec l'opérateur ternaire sur un return? J'appelle ça du code de merde, sans parler des affectations au milieu: l'auteur ne veut pas que l'on puisse comprendre ce qui se fait.

      La raison est le code-golfing, c'est juste résoudre une équation du second degré. Le discriminant est b²-4ac et les solution sont (b-sqrt(discriminant))/2a et (b+sqrt(discriminant))/2a.

      Errrr…. spheres était un table de taille de fixe, on peut constater ici plusieurs erreurs, possiblement optimisée par le compilo, mais peut-être pas:

      • a chaque appel de la fonction intersect, on refait une division inutile: n devrais être une constante, calculé une seule fois. Et pas un double.
      • cast double vers int inutile pour n.
      • for(int…) vraiment? Même en C ou C++03 on faisait mieux, avec les pointeurs. Du C++11 moderne, donc de moins de 10 ans, utiliserais juste un range for. Bon, ici, il semble réutiliser l'entier pour le retourner dans le cas ou il trouve une intersection, mais vu que le code est imbuvable, difficile de dire si on ne peut pas s'en passer.

      N'importe quel compilateur actuel fera du constant folding + hoisting et transformera une division par une constante en code optimal avec les optimisations.

      Aussi:

      Nim 1.2.0 (GCC 10.1), flag -d:danger

      Donc, version récente: "1.2.0 2020-04-03".

      Pourtant, il n'utilise pas C++20, pourquoi? Ça aurait permis d'éviter certaines implémentations, genre clamp vs std::clamp.

      Le code original date de 2008.

      • [^] # Re: Aie mes yeux...

        Posté par  . Évalué à 3 (+0/-0).

        tu arrives un peu après le débat. Est-ce que tu pourrais commencer une news sur la description de Nim ?

        "La première sécurité est la liberté"

        • [^] # Re: Aie mes yeux...

          Posté par  . Évalué à 2 (+2/-0).

          On m'a envoyé la dépêche et je me suis inscrit pour éclaircir les choses.

          Malheureusement la communauté LinuxFR ne me semble pas très accueillante donc pour l'instant je ne compte pas user de mon temps libre pour une news où je me fais descendre par des personnes qui lisent articles de travers.

          • [^] # Re: Aie mes yeux...

            Posté par  . Évalué à 2 (+0/-0).

            la communauté LinuxFR ne me semble pas très accueillante

            Tu m'en vois désolé.

            des personnes qui lisent articles de travers.

            Autant je suis d'accord qu'il y a méprise, autant je vois passer beaucoup trop de bench qui ne sont que des concours de pénis pour méfiants quand il y a à mon avis que très peu d'explications.

            Une dernière fois, désolé que la discussion se soit trop envenimée.

      • [^] # Re: Aie mes yeux...

        Posté par  . Évalué à 2 (+0/-0).

        Désolé, je n'avais pas du tout compris les choses ainsi.

        De fait il a été code-golfé en 100 lignes.

        Mouai, ok. Perso je considère que le golf est une forme d'obfuscation. C'est rigolo à faire, mais ça ne présente aucun intérêt.

        N'importe quel compilateur actuel fera du constant folding + hoisting et transformera une division par une constante en code optimal avec les optimisations.

        J'avais aussi en tête que les compilateurs étaient très capables d'optimiser vachement bien le code eux-même, il y a 2-3 ans.
        Depuis, j'ai passé google-perfools sur quelques logiciels qui font un peu de calcul, et… j'ai de gros doutes.
        Souvent, sortir un bête calcul d'une boucle améliore les performances.

        Le code original date de 2008.

        En fait, je pensais que le code avais été fait pour le bench, désolé. Du coup, c'est en effet du C++ écrit dans un standard si vieux que certains considèrent (moi, à minima) qu'il ne s'agit plus du même langage.

Envoyer un commentaire

Suivre le flux des commentaires

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