IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Recherche de code Math optimisé


Sujet :

Langage Delphi

  1. #1
    Futur Membre du Club
    Inscrit en
    Novembre 2005
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 12
    Points : 8
    Points
    8
    Par défaut Recherche de code Math optimisé
    Bonjour à tous,

    Voila, je cherche du code assembleur optimisant (quitte à perdre de la precision) pour les fonctions de trigo de base (tan, sin, cos, atan, acos, asin).

    Dans l'esprit de celle que j'ai deja sur ln et exp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
     
    const
      ln2=0.693147181;
      dexpA:double=$100000/ln2;  // 2^20 / ln2
      dlnA:double=ln2/$100000;
      fexpA:double=$800000/ln2;  // 2^23 / ln2
      flnA:double=ln2/$800000;
      fexpC=545947;
      flnC=545947;
      dexpC=68243;
      fnexpA:double=-$800000/ln2;  // 2^23 / ln2
      fone:single=1;
      fdivA:single=-1;
     
    function dexp(x:single):double;
    var y:double;
    asm
      fld x
      fmul dexpA
      fistp dword ptr y[4]
      mov dword ptr y[0],0
      add dword ptr y[4],($3FF00000-dExpC)
      fld y
    end;
     
    function dln(x:double):double;
    asm
      sub dword ptr x[4],($3FF00000-dExpC);
      fild dword ptr x[4]
      fmul dlnA
    end;
     
    function fexp(x:single):double;
    // ~ 10x faster
    asm
      fld x
      fmul fexpA
      fistp dword ptr x
      add dword ptr x,($3F800000-fExpC)
      fld x
    end;
     
    function fexp1(var x:single):double;
    // special case when x can be prevented from being pushed on the stack
    // ~14.5x faster
    asm
      fld dword ptr [eax]
      fmul fexpA
      fistp dword ptr [esp-4]
      add dword ptr [esp-4],($3F800000-fExpC)
      fld dword ptr [esp-4]
    end;
     
     
    function fln(x:single):double;
    // ~ 7x faster
    // very poor accuracy as x -> 1.0
    asm
      sub dword ptr x, ($3F800000-flnC)
      fild dword ptr x
      fmul flnA
    end;
     
    function fdiv(x:single):single;
    // ~20 faster in some circumstances
    var y:single;
    asm
      sub dword ptr x, ($3F800000-flnC)
      fild dword ptr x
      fmul fdivA
      fistp dword ptr y
      add dword ptr y,($3F800000-fExpC)
      fld y  // 1/x
    end;
     
    function sigmoid1(x:single):single;
    // ~1.6x faster than 1/(1+fexp)
    asm
      fld x
      fmul fnexpA
      fistp dword ptr x
      add dword ptr x,($3F800000-fExpC)
      fld x
      fld dword ptr fone
      fadd st(1),st(0);
      fdivr
    end;
     
    function sigmoid2(var x:single):single;
    // ~2.3x faster than 1/(1+fexp)
    asm
      fld dword ptr [esp-4]
      fmul fnexpA
      fistp dword ptr [esp-4]
      add dword ptr [esp-4],($3F800000-fExpC)
      fld dword ptr [esp-4]
      fld dword ptr fone
      fadd st(1),st(0);
      fdivr
    end;
     
    function sigmoid0(x:single):single;
    begin
      result:=1/(1+fexp(-x));
    end;
    Note : je ne comprends pas tres bien ce code.
    Comment reduire la precision de la fonction de base Delphi :
    CAD :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function Tan(const X: Extended): Extended;
    { 
    Tan := Sin(X) / Cos(X) }
    asm
            FLD    X
            FPTAN
            FSTP   ST(0)      { FPTAN pushes 1.0 after result }
            FWAIT
    end;
    Merci pour votre aide (pour piger et / ou trouver du code qui le fait).

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 548
    Points : 25 118
    Points
    25 118
    Par défaut
    Il te faudrait étudier l'assembleur FLD gére différent type de registre tout comme FSTP

    Attention ne mélange surtout pas de single et des extended !
    Déjà pour gagner du temps, utilise strictement le type des paramètres des fonctions, mesure le temps pour A et pour B

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var
      S, RS: Single;
      E, RE: Extended;
    begin
      RS := Tan(S); // A
      RE := Tan(E); // B
    end;
    Pour moi vouloir utiliser des codes assembleurs que l'on est incapable de maintenir n'est pas une bonne idée ou alors il faut acheter des bibliothèques pérenne ou encore en trouver des OpenSource extrêmement bien documentées !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Futur Membre du Club
    Inscrit en
    Novembre 2005
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Merci pour les infos.

    Pour moi vouloir utiliser des codes assembleurs que l'on est incapable de maintenir n'est pas une bonne idée ou alors il faut acheter des bibliothèques pérenne ou encore en trouver des OpenSource extrêmement bien documentées !
    Ben, oui, je ne peux qu'être d'accord. Comprendre l'assembleur m'interesse dans l'absolu, et il faut bien commencer quelque part...
    Je regarde du côté que tu m'as indiqué...

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 747
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 747
    Points : 13 314
    Points
    13 314
    Par défaut
    Tu peux poser tes questions assembleur dans le forum dédié.
    Voici par exemple une discussion qui pourrait t'intéresser

Discussions similaires

  1. Réponses: 16
    Dernier message: 07/08/2006, 13h11
  2. [LookAndFeel] Recherche de code
    Par Keldrhyn dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 19/06/2006, 09h56
  3. recherche de code de messagerie
    Par gaviotte dans le forum ASP
    Réponses: 1
    Dernier message: 23/05/2006, 00h01
  4. rechercher dans un fichier optimisé?
    Par gregcat dans le forum Langage
    Réponses: 3
    Dernier message: 20/12/2005, 01h13
  5. Lier du code C optimisé et du code ASM non optimisé
    Par garybaldi dans le forum x86 32-bits / 64-bits
    Réponses: 3
    Dernier message: 07/09/2005, 16h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo