Crunchez vos adresses URL
|
Rejoignez notre discord
|
Hébergez vos photos
Page 3 sur 334 PremièrePremière 12345678910111353103 ... DernièreDernière
Affichage des résultats 61 à 90 sur 10008
  1. #61
    Bah non au contraire, on va monopoliser encore un peu. Je me sentais tout seul sur mon topic OpenGL à discuter de C++. J'ai enfin trouvé quelqu'un qui me comprend.
    Sinon je ne dis pas que les templates sont une alternative à la POO, ça va avec bien entendu. Mais c'est tellement plus amusant que des objets tout simples.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  2. #62
    ahhhhhh d'accord Pour en remettre une couche, je me souviens d'une version ancienne des bibliothèques RogueWave (bibliothèques de conteneur, finalement rendue obsolète par l'adoption de cette putain de STL) ou il y avait systématiquement deux implémentations possibles pour toutes les catégories de template:
    1. template: classique quoi, il fallait instancier le conteneur sur le type qu'on voulait collectionner
    2. basé sur pointeurs et héritage: il fallait faire dériver la classe qu'on voulait collectionner de leur classe de base

    C'est vieux maintenant mais c'était plutôt bien foutu, et illustrait parfaitement les avantages et inconvénient des 2 approches d'ailleurs.

    Bref, c'est vieux tout ça, je sens que je fais mon vieux croûton la..

    Sinon, il y a des avancées dans la norme 0X dont je ne capte pas bien l'intérêt, genre les listes d'initialisation: bof. Je n'arrive pas à trouver un cas d'utilisation.

  3. #63
    Regarde Boost.Intrusive ça va te plaire. Ils font pareil, avec des conteneurs basés sur un ajout de membres aux classes à collectionner pour les relier entre elles dans les conteneur (genre pointeur de liste chainée...) mais avec des classes à hériter pour faciliter le boulot, et une interface similaire à la STL ensuite.

    Je pense que les listes d'initialisation ça va un peu avec la nouvelle syntaxe pour l'itération dans un conteneur. On peut maintenant écrire
    Code:
    for(type v : conteneur) {
    ...
    }
    qui est compilé en
    Code:
    for(iterator i = begin(conteneur); i != end(conteneur); ++i) {
      type v = *it;
      ...
    }
    Et forcément, begin() et end() ne marchent pas avec les vieux tableaux statiques. Donc on doit passer par un conteneur STL (ou autre), et les listes d'initialisation permettent de faire ça aussi facilement qu'avec un array statique.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  4. #64
    oui, ça va "avec", c'est vrai, et ça poussera (un peu) plus à l'utilisation de classes plutôt que de tableaux à la C, mais les seules fois ou j'utilise des listes d'initialisation c'est dans les tests unitaires ou effectivement je remplis en dur dans le code des conteneurs pour mes tests. Bon, c'est toujours ça, hein.

    Je vais jeter un oeuil à Boost, pour le boulot on avait utilisé les bibliothèques RogueWave+STL (il y a 10 ans déjà, putain) et pour mon projet perso, je peux largement me contenter de la STL et d'implémentations perso des patterns habituels (j'ai besoin de GROSSES perfos)

    ---------- Post added at 18h24 ---------- Previous post was at 18h12 ----------

    P.S. après lecture je confirme, Rogue wave proposait bien une implémentation "intrusive" des conteneurs
    Après analyse, je confirme aussi que ma productivité a été minée par CPC, qui est donc responsable de la crise mondiale.

  5. #65
    Citation Envoyé par rOut Voir le message
    Regarde Boost.Intrusive ça va te plaire. Ils font pareil, avec des conteneurs basés sur un ajout de membres aux classes à collectionner pour les relier entre elles dans les conteneur (genre pointeur de liste chainée...) mais avec des classes à hériter pour faciliter le boulot, et une interface similaire à la STL ensuite.

    Je pense que les listes d'initialisation ça va un peu avec la nouvelle syntaxe pour l'itération dans un conteneur. On peut maintenant écrire
    Code:
    for(type v : conteneur) {
    ...
    }
    qui est compilé en
    Code:
    for(iterator i = begin(conteneur); i != end(conteneur); ++i) {
      type v = *it;
      ...
    }
    Et forcément, begin() et end() ne marchent pas avec les vieux tableaux statiques. Donc on doit passer par un conteneur STL (ou autre), et les listes d'initialisation permettent de faire ça aussi facilement qu'avec un array statique.
    Aka un foreach en java quoi ?
    Je fais pas de C++, mais c'est une nouveauté ?
    "If God had wanted you to live he would not have created me!"

  6. #66
    Ouais. Mais en fait c'est plus souple qu'un foreach vu que ça utilise simplement un appel à begin(conteneur) et end(conteneur) (et ++ de ton itérateur), après tu peux surcharger begin et end comme tu veux pour pervertir bien comme il faut le comportement du for. Genre qu'au lieu de faire une boucle, ça sélectionne un seul élément aléatoirement dans ton conteneur, sur lequel va s'executer le contenu du for (c'est un exemple de truc absurde et inutile qu'il faut évidemment implémenter).

    ---------- Post added at 19h20 ---------- Previous post was at 19h15 ----------

    En fait Wikipede me dit que c'est aussi censé marcher pour les array statiques. Je ne sais plus ce que j'avais testé.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  7. #67
    peut-être un compilateur qui n'était pas conforme, héhé.

    @Tiramisou: oui c'est nouveau en C++, et fait à la sauce C++ c'est à dire qu'on peut tout redéfinir comme l'expliquait rOut plus haut...

  8. #68
    Comme c'est l'été et que le CryEngine 3 à été lâché dans la nature, voici un devoir de vacances.

    Dans un fichier au fin fond du code du CryEngine, on trouve la fonction suivante :
    Code:
    00874 ILINE int32 iszero(f64 x) {
    00875         union { f32 f; int32 i; } u;
    00876         u.f=(f32)x;
    00877         u.i&=0x7FFFFFFF;
    00878         return -((u.i>>31)^(u.i-1)>>31);
    00879 }
    http://www.gamedev.stjepan.net/ce3sd...ce.html#l00874

    Exercice : en ignorant pour l'instant la raison d'être de cette fonction et ce qu'elle fait et pourquoi elle le fait, lister et expliquer les erreurs grossières qu'elle contient. Il y en a au moins 3 de vraiment grosses.

    Le premier qui trouve les 3 gagne rien du tout.

    Edit: en question bonus, trouver la ou les substances hallucinogènes qui sont consommées chez Crytek.

  9. #69
    Heu alors, j'avoue que j'ai un peu de mal à déterminer quelles sont les erreurs grossières (parce que c'est quand même assez dégueu comme code) mais je fais un pronostic :
    1. Un gros présupposé sur la manière dont le type f32 (float sur 32bit suppose-je) est codé en mémoire. C'est toujours le cas quand on fait la transformation magique float<->int, comme c'est le cas dans l'invert sqrt de "Carmack". Même si ça marche généralement en pratique, ça reste une très mauvaise idée à mon avis.
    2. La même chose sur la manière dont est codé l'int32 en mémoire, en supposant que le signe est sur le premier bit, je ne suis pas sûr que ce soit obligatoire et cela dépend de la manière dont le compilo a envie de faire les choses (?).
    3. Des histoires de shifts un peu débiles.
      1. Avec "u.i&=0x7FFFFFFF" on efface le premier bit (le signe de l'entier).
        Du coup "u.i>>31" donne ensuite toujours 0, puisqu'on shifte de 31 bits, c'est à dire que l'on décale tous les bits vers la droite de 31 bits (il ne reste donc que le premier).

        De plus sur un entier signé, c'est un logical shift qui sera certainement appliqué, donc le bit du signe sera copié dans tous les autres bits par cette operation. Mais ça ne change rien.
      2. (u.i-1)>>31 est un peu plus compliqué, mais ne retourne rien de bien interessant non plus.
        Comme 3a, c'est le signe de (u.i-1) qui va être copié dans tous les autres bits, or u.i-1 sera négatif dans le seul cas ou u.i vaut 0.
        Ce sera le cas si initialement le bit du signe valait 1 ou 0, et que tous les autres valaient 0.
        C'est à dire si u.i valait 0 ou -2147483648 (puisqu'on a effacé le premier bit à la ligne précédente).

        Dans ce cas (u.i-1)>>31 retourne -1, sinon il retourne 0.

    Je ne parle même pas du xor entre 0 et quoi que ce soit d'autre, qui retourne évidemment "quoi que ce soit d'autre".

    En conclusion, ce que fait cette merveilleuse fonction, c'est vérifier si le float passé en entrée, arrondi sur la capacité d'un float32 vaut ±0, dans le codage IEEE754 binary32, c'est à dire si tous les bits sont à 0 sauf le premier, ce qui est légèrement plus facile à vérifier que toute cette merde.

    Moi qui croyais que dans les jeux vidéos on arrivait à éviter le code crade et inutile...
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  10. #70
    Ah mais tu as raison, en fait il y a une erreur qui n'en est pas une. Au temps pour moi.

    Le 1. ne me gêne pas spécialement. Le code présuppose que la machine suit le codage d'IEEE-754 et code les flottants et les entiers avec le même endianness (encore heureux!). L'astuce de l'union n'est pas portable en théorie, mais elle l'est en pratique et ça ne dérange que les standard nazis.
    Idem pour le 2. Le C peut être compilé sur des machines qui ne représentent pas les nombres en complément à 2, mais en pratique…

    Le 3a, c'était une de celles auxquelles je pensais.

    Bien vu pour 3b, en fait je n'avais pas fait gaffe que -0 était converti en +0 quand il prenait la valeur absolue…

    L'autre problème est la conversion en simple précision qui peut provoquer un underflow et renvoyer 1 pour un nombre non-nul en entrée.

    Tout ça pour pas écrire return x == 0;
    (qui sero au moins aussi rapide que ne serait-ce que la première conversion de binary64 vers binary32…)

  11. #71
    L'autre problème est la conversion en simple précision qui peut provoquer un underflow et renvoyer 1 pour un nombre non-nul en entrée.
    C'est à dire ? J'ai la flemme d'y réfléchir.

    Par contre je ne comprends quand même pas pourquoi ils ont codé ça. Je veux dire, le but d'un code et à fortiori de celui d'un jeu vidéo c'est quand même d'utiliser les méthodes les plus efficaces pour effectuer une opération. Alors pourquoi ça ?

    Enfin, sinon je ne suis quand même pas d'accord sur "Tout ça pour pas écrire return x == 0", parce qu'il y a quand même une opération de conversion double -> float qui doit rendre == 0 toutes les valeurs qui ne sont pas représentables par un float. A moins que ce ne soit ça l'underflow dont tu parles et qui retourne 1 ?
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  12. #72
    Oui. Quand une fonction s'appelle iszero et qu'elle est surchargée pour float, double, int32 et int64 et qu'il n'y a pas de commentaires, j'ai tendance à supposer que ça sert à tester si un nombre est nul ou pas.
    Bien sûr en l'absence de spec on peut effectivement imaginer n'importe quoi, par exemple que c'est une fonction spéciale pour insérer un temps d'attente qui dépend de l'efficacité du compilateur à détecter les opérations booléennes triviales.

    ---------- Post added at 23h54 ---------- Previous post was at 23h50 ----------

    Ah, en fait la troisième erreur elle est dans la fonction d'à-côté:
    Code:
    00890 ILINE int32 iszero(int32 x) {
    00891         return -(x>>31^(x-1)>>31);
    00892 }
    Je suis sûr qu'en plus le mec qui a pondu ça devait être super fier de lui.

  13. #73
    Non mais ce fichier contient un potentiel de fail assez énorme quand même...
    Code:
    00887 ILINE int32 isnonneg(int32 x) {
    00888         return (int32)((uint32)x>>31^1);
    00889 }
    Code:
    00890 ILINE int32 iszero(int32 x) {
    00891         return -(x>>31^(x-1)>>31);
    00892 }
    Code:
    00900 // AMD64 port: TODO: optimize
    00901 ILINE int64 iszero(__int64 x) 
    00902 {
    00903         return -(x>>63^(x-1)>>63);
    00904 }
    C'est une blague, c'est pas possible...

    ---------- Post added at 23h58 ---------- Previous post was at 23h57 ----------

    Le commentaire est juste mythique.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  14. #74
    Moi ce qui me fait tripper aussi c'est
    Code:
    #define gf_PI  f32(3.14159265358979323846264338327950288419716939937510) // pi
    Histoire d'être sûr.

    (C'est pas comme s'il y avait un théorème datant des années 1980 qui montrait qu'il suffisait de 8 chiffres décimaux significatifs pour les conversions décimal->binary32, hein.)

  15. #75
    Citation Envoyé par Møgluglu Voir le message
    Ah, en fait la troisième erreur elle est dans la fonction d'à-côté:
    Code:
    00890 ILINE int32 iszero(int32 x) {
    00891         return -(x>>31^(x-1)>>31);
    00892 }
    Je suis sûr qu'en plus le mec qui a pondu ça devait être super fier de lui.
    Prenons x=0x80000000,
    x>>31 donne 0xFFFFFFFF=-1,
    x-1 donne... oh shi



    ---------- Post added at 00h11 ---------- Previous post was at 00h11 ----------

    Citation Envoyé par Møgluglu Voir le message
    Moi ce qui me fait tripper aussi c'est
    Code:
    #define gf_PI  f32(3.14159265358979323846264338327950288419716939937510) // pi
    Histoire d'être sûr.

    (C'est pas comme s'il y avait un théorème datant des années 1980 qui montrait qu'il suffisait de 8 chiffres décimaux significatifs pour les conversions décimal->binary32, hein.)
    Il en manque, les gros nuls. :nelson:

    ---------- Post added at 00h22 ---------- Previous post was at 00h11 ----------

    J'ai peut être trouvé un indice sur la raison de tout ça.

    Code:
    00236 template<> ILINE int clamp_tpl<int>( int X, int Min, int Max ) 
    00237 {       
    00238         //implement branchfree using masks
    00239         const uint32 minMask = (uint32)((Min-X) >> 31);
    00240         const uint32 maxMask = (uint32)((X-Max) >> 31);
    00241         int res = minMask & X | ~minMask & Min;
    00242         res = maxMask & res | ~maxMask & Max;
    00243         return res;
    00244 }
    Le but serait d'avoir du code branch-free (?), optimisé pour la PS3:
    http://cellperformance.beyond3d.com/...imination.html

    Le truc c'est que je ne suis pas sûr de voir de branches dans "return x==0", ou alors il y en a de cachées dès que des comparaisons booléennes entrent en jeu ?
    Le même genre de code chelou là:
    http://cellperformance.beyond3d.com/...-06-added.html
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  16. #76
    Bien essayé. Mais non, c'est d'autant plus débile que le SPU du Cell a plein d'instructions de comparaisons qui écrivent directement le résultat dans un registre généraliste, sous forme de masque.

  17. #77
    Okaaay

    ---------- Post added at 02h01 ---------- Previous post was at 00h32 ----------

    Du coup j'ai parcouru le site en question, et je me dis quand même que le mec a l'air sûr de lui (et apparemment c'est pas non plus un abruti), donc j'aimerais bien savoir ce que tu penses de ça, par exemple :
    http://cellperformance.beyond3d.com/...eger-code.html

    Mes compétences en assembleur sont largement dépassées et je ne sais pas trop quoi penser du "No comparison operations, thus no dependencies on CR at all". En gros il dit qu'il faut éviter d'utiliser le Comparison Register (quoi que ce puisse être).

    Je ne sais pas si c'est spécifique au Cell ou si c'est d'une manière générale.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  18. #78
    Citation Envoyé par rOut Voir le message
    Je ne sais pas si c'est spécifique au Cell ou si c'est d'une manière générale.
    Ah oui, tu/il a raison. Il parle du Cell PPU (un PowerPC classique) alors que je pensais au SPU.
    J'ai entendu suffisamment de mal des outils de Sony pour être prêt à croire que les compilateurs pour Cell sont tellement mauvais qu'il faille leur dire ça :
    Code:
    uint32_t mask_comb = (uint32_t)((int32_t)( test_comb | -test_comb ));
    Pour qu'ils fassent ça :
    Code:
    uint32_t mask_comb = ~-!test_comb;
    (Qui est vachement plus élégant non ? )

    Ou en un peu moins obfusqué :
    Code:
    uint32_t mask_comb = -(test_comb != 0);
    Mais tu notera qu'ici on utilise la convention vrai=-1=0xffffffff, ce qui permet d'appliquer des masques sur les valeurs. Dans le code de Crytek, la convention est celle du C avec vrai=1, donc ça n'apporte rien par rapport à l'opérateur de comparaison (x != 0), dont la sémantique correspond exactement.

    Oui, c'est spécifique aux processeurs in-order dont le registre de drapeaux n'est pas chargeable facilement dans un registre généraliste, qui ont des mauvais prédicteurs de branchement, et dont le compilateur est inepte.
    Accessoirement, ça peut aussi servir quand tu fais du SIMD dans un registre (SWAR, genre calcul parallèle sur 4 nombres 8 bits codés dans un entier 32 bits)

    En tout cas, sur des x86, des ARM, ou même des GPU, c'est clairement une connerie.

    Sinon je suis tombé sur la page des tarés du SWAR :
    http://aggregate.org/MAGIC/#Comparis...k%20Conversion

    et effectivement ça semble correspondre à ce que le programmeur voulait faire. Pourquoi il a mis un xor au lieu d'un or, le mystère reste entier. Peut-être qu'il s'est gouré de ligne en recopiant depuis le Hacker's delight et a pris la version signe-magnitude.
    (Ce qui est particulièrement ironique, c'est qu'il prenne la peine d'effacer le bit de signe des flottants, alors que ce coup-là ça marcherait directement avec (x ^ -x).)

  19. #79
    Moi je voit qu'une seule erreur, il y a pas de commentaires
    Du coup sans savoir où, quand, comment utiliser la fonction, difficile de dire s'il y a des erreurs.
    Mais venant du Cry Engine, s'ils l'utilisent il doit y avoir un intérêt.

    Sur PS3 aucune idée, mais sinon dans certains cas, dans le code généré par les compilateurs il y a des appels de fonctions pour une conversion par exemple, qui sont relativement lent, et ça peut valoir le coup de remplacer ça par quelques lignes de code en inline.
    Anything that can go wrong will go wrong.

  20. #80
    Citation Envoyé par TheMothMan Voir le message
    Moi je voit qu'une seule erreur, il y a pas de commentaires
    Du coup sans savoir où, quand, comment utiliser la fonction, difficile de dire s'il y a des erreurs.
    Mais venant du Cry Engine, s'ils l'utilisent il doit y avoir un intérêt.
    Ha ha, cher ami quelle naïveté. Les commentaires ça prend du temps à écrire et ça pompe le budget inutilement.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  21. #81
    Va dire ça à mon patron
    Anything that can go wrong will go wrong.

  22. #82
    Non mais disons que c'est une mauvais habitude très très très répandu, partout dans l'industrie. Donc perso ça ne m'étonne plus.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  23. #83
    héhé, je viens de relire tout ça, je crois que ce qui me troue le plus c'est de publier du code dans cet état la dans la nature. C'te honte.

    Sinon, sans doute qu'avec un commentaire on se prendrait moins la tête, et on comprendrait comment ils en sont arrivé la. Beurk.

  24. #84
    Surtout pour CryTek quoi, voilà la mauvaise pub.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  25. #85
    Messieurs, je ne suis pas programmeur.

    J'ai trouvé, comme tout le monde, la manière de vérifier un zéro quelque peu bizarre, car je ne suis pas programmeur, mais je connais quand même un peu le C++.
    CE3 est un des moteurs de rendu graphique le plus rapide du marché, il est très certainement dans les 3 premiers, et je suis gentil.
    Croyez-vous que ce serait le cas si leur code était truffé de trucs stupides et inutilement gourmands ? Croyez-vous que les vérificateurs / testeurs / whatever laisseraient passer ça sans broncher, surtout pour une méthode appelée un paquet de fois par seconde ? I don't think so.

    Mogluglu a très bien montré du doigt la raison probable, contourner les limitations du compilateur afin d'avoir un code binaire le plus rapide possible.
    Chai pas vous mais moi, un gars qui est capable de coder en fonction du comportement futur du compilateur me donne plus envie de le respecter que de me payer sa poire.
    I am Moanaaaaaaa !!! (et en version legit!)

  26. #86
    Bin tu sais, j'ai vu des choses autrement plus dégueu dans des boites censées faire des applis ou une microseconde peut couter des millions. Donc comme je le disais, effectivement ça m'étonne et je ne comprend pas comment c'est possible d'avoir un tel code chez CryTek, mais le fait est que c'est visiblement le cas.

    C'est possible que ce soit du code optimisé pour la PS3 (comme semble l'indiquer le site que j'ai pu trouver qui fait des choses similaires), mais ce n'est pas clairement pas optimisé pour les autres plateformes. Alors au final est-ce que ça vaut le coup ?

    Peut être que leur conclusion, au contraire, c'est "On ne va pas se faire chier a avoir du code spécifique pour chaque plateforme, utilisons un code dont l'optimisation est indispensable sur PS3, et qui sera un peu moins optimisé pour les autres plateformes mais c'est pas grave, les PC étant bien plus rapides qu'une PS3 de nos jours, ça ne se verra pas".

    D'autres points sont vraiment de la connerie, comme les décimales de PI, qui certes ne vont pas plomber les performances, mais dénotent un certain manque de reflexion du mec qui a codé ça.

    ---------- Post added at 20h05 ---------- Previous post was at 20h04 ----------

    Mes respects au gars qui va devoir maintenir le code, une fois que l'auteur d'origine sera barré par contre. Le pauvre gars va saigner des yeux.
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  27. #87
    C'est beau cet idéalisme et cette confiance aveugle.

    La réalité, c'est que les programmeurs ne sont pas formés pour ça (l'architecture des ordinateurs, les systèmes de représentation des nombres et l'arithmétique, au mieux ça a été vu en cours vite fait et oublié encore plus vite fait, au pire ça a été "mal appris", comme quand on t'explique que faut faire les comparaisons de flottants avec des epsilons ou qu'il faut éviter les branchements dans le code CPU…), qu'ils ont plein d'autres choses bien plus importantes dont ils doivent s'occuper dans un jeu vidéo, et que surtout, programmer du code correct c'est très difficile.

    On a vu des fusées exploser en vol à cause d'overflows, des croiseurs planter en pleine mer à cause de division par zéro, des missiles rater leur cible de 50m à cause de conversions décimal/binaire.

    Pourquoi les programmeurs de jeu vidéo seraient mieux qualifiés et auraient des meilleures procédure de QA que les programmeurs de ces systèmes critiques ?

    Du code comme ça, c'est standard dans l'industrie et ça n'a rien de surprenant.

    Ça n'apparaît pas clairement, mais mon but n'est pas juste de me payer la poire des devs de Crytek. Mon espoir est aussi que ça puisse servir d'exemple à éviter.
    (Sinon, ce que je dis plus haut c'est que ce code n'a aucune raison d'être, compilateur ou pas. C'est un fail, c'est tout. Ça arrive.)

  28. #88
    Du code comme ça, c'est standard dans l'industrie et ça n'a rien de surprenant.
    Hélas

    ---------- Post added at 20h42 ---------- Previous post was at 20h41 ----------

    comme quand on t'explique que faut faire les comparaisons de flottants avec des epsilons ou qu'il faut éviter les branchements dans le code CPU…
    J'ai pas d'opinion là dessus, mais tu as des infos sur le pourquoi ça ne sert à rien ces deux choses ?
    "Dieu est mort" · "Si le téléchargement c’est du vol, Linux c’est de la prostitution."

  29. #89
    Citation Envoyé par rOut Voir le message
    J'ai pas d'opinion là dessus, mais tu as des infos sur le pourquoi ça ne sert à rien ces deux choses ?
    Les epsilons : comparer 2 nombres à un epsilon près, ça revient à considérer une borne sur l'erreur absolue directe. Or, ce n'est presque jamais ce qu'on veut. Et comment choisir l'epsilon ? L'erreur directe n'est pas intuitive du tout. En général, c'est plutôt l'erreur inverse qu'on sait estimer. (wiki à la rescousse)
    Je n'y connais rien en analyse numérique, mais il me semble que la plupart des calculs utilisés en géométrie peuvent être arbitrairement mal conditionnés, c'est à dire qu'une petite erreur en entrée peut être amplifiée pour en générer une énorme en sortie. Typiquement dès qu'on commence à calculer des projections. Dans ce cas, le seul epsilon raisonnable est +infini…

    Il n'y a pas de solution miracle, à part comprendre son calcul et d'où proviennent les erreurs. Il y a des outils, comme l'arithmétique d'intervalles, mais ça ne fait pas de miracles non plus.

    Pour les branchements :
    - Dans un CPU superscalaire out-of-order moderne, le prédicteur de branchement devine les destinations de saut à l'avance avec une précision diabolique. Quand un branchement est correctement prédit, l'instruction de saut coûte typiquement zéro cycles. Après il y a des jeux d'instructions SIMD genre SSE ou Cell SPU qui ne sont même pas foutus de suivre des branchements, et où on n'a pas le choix (du moins quand on programme en assembleur ou juste au-dessus).

    - Dans un GPU, c'est encore mieux. Quand il rencontre une instruction de branchement, le matériel regarde si toutes les voies SIMD vont dans la même direction. Si oui, il ne parcourt que la branche concernée. Sinon, il parcourt les deux.
    Écrire du code branchless pour un GPU, c'est particulièrement con, parce que ça revient à le forcer à exécuter les deux branches entièrement (sans possibilité d'éteindre les unités inactives pour économiser l'énergie), et en plus de le faire exécuter le code supplémentaire qui recolle les morceaux.

    Bien sûr, il y a une foule de programmeurs qui sont convaincus du contraire. Je suis sûr que c'est encore à cause du Cell.

  30. #90
    Citation Envoyé par Møgluglu Voir le message
    On a vu des fusées exploser en vol à cause d'overflows, des croiseurs planter en pleine mer à cause de division par zéro, des missiles rater leur cible de 50m à cause de conversions décimal/binaire.
    Ou une sonde de la NASA s'écraser sur Mars à cause d'un oubli de conversion entre système impérial et système métrique...

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •