mratsim a écrit 8 commentaires

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

    Posté par  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 2.

    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  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 1.

    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  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 1.

    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  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 1.

    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  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 3.

    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  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 3.

    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  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 2.

    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  . En réponse au lien Nim plus rapide que C++ sur du ray tracing. Évalué à 2.

    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.