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 :

Additions avec + de 20 chiffres significatifs avec une fonction en Asm à optimiser


Sujet :

Langage Delphi

  1. #21
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut


    un mixte des deux

    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
     
    const PreCalcResult : Array [96..115] of char =
    ({96}'0','1','2','3'
    ,'4','5','6','7','8','9','0','1','2','3'
    ,'4','5','6','7','8','9');
     
     
    Function Addition2EBVbis(Const s1: String; Const s2: String; Len: Cardinal): String;
    Var
      i : integer;
      retenue : byte;
      offset  : integer;
      p:PChar;
    Begin
      SetLength(result,len);
      p:=@Result[len];
      retenue := 0;
      For i := len Downto 1 Do
      Begin
        offset := integer(S1[i]) + integer(S2[i]) + retenue;
        P^ := PreCalcResult[offset];
        retenue := byte(offset>= 109);
        dec(p);
      End;
    End;
    @+ Phil
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  2. #22
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Réponses à vos derniers messages d'hier d'avant 18 heures :

    J'ai fait les tests comparatifs suivants :

    A) / message d'Anapurna dh'Hier, 16h38 avec sa procedure AdditionProc(Const s1: pchar; s2: pchar; out s3 : String; Len: integer) qu'il a fallu rectifier un peu comme suit afin qu'elle marche sans message d'erreur :
    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
    //procedure AdditionProc(Const s1: pchar; s2: pchar; out s3 : String; Len: integer);
    procedure AdditionProcA(Var s1,s2 : pchar; out s3 : String; Len: integer);
    var       i, retenue, offset: integer; p3: PChar;
    Begin     retenue := 0;
              SetLength(s3,Len); //<- initialisation
              inc(s1,Len-1); inc(s2,Len-1); //<- sinon on ne peut pas faire ni dec(s1) ni dec(s2) par la suite
              p3:= @s3[Len];
              for i := len downTo 1 do
              begin offset := integer(s1^) + integer(s2^) + retenue;
                    p3^ := PreCalcResultA[offset]; //<- ici tableau simplifié (pas eu besoin de modifier le reste du code pour utiliser le tableau simplifié)
                    retenue := PreCalcRetA[offset]; //<- dito ci-dessus
                    dec(s1);
                    dec(s2);
                    dec(p3);
              end;
    end;
    Temps d'exécution (Pentium III 1,13 Ghz) Pour NbrCall = 100000;
    1) avec const PreCalc : Array [0..115] of char :
    - mis 254 ms pour chaines de 128 caractères
    - mis 358 ms pour chaines de 228 caractères
    -mis 14670 ms pour chaines de 11400 caractères

    2) avec const PreCalc : Array [96..115] of char
    - mis 220 ms pour chaines de 128 caractères
    - mis 347 ms pour chaines de 228 caractères
    - mis 14680 ms pour chaines de 11400 caractères
    le gain de temps résultant de l'utilisation du tableau simplifié est sensible ( 254/220) dans le cas de chaines courtes ou plus exactement dans le cas où la boucle a le temps de s'effectuer sans être interrompue par Windows qui reprend la main quand ça lui chante.

    B) / message d'Eric Boisvert Hier, 16h24 : tests avec sa procedure AdditionProc(Const s1:string; var s2: String; Len: integer) pour NbrCall = 100000 :
    - mis 210 ms pour chaines de 128 caractères
    - mis 247 ms pour chaines de 228 caractères
    - mis 9206 ms pour chaines de 11400 caractères

    C) / message de Sjrd d'Hier, 17h18 : tests avec sa function Addition(const Val1, Val2 : string) : string : malgré le fait que cette fonction renvoie comme résultat une chaine non-numérique (je n'ai pas encore identifié la cause) j'en ai quand-même testé la vitesse résultant de sa structure pour NbrCall = 100000 :
    - mis 362 ms pour chaines de 128 caractères
    - mis 645 ms pour chaines de 228 caractères
    - mis 28686 ms pour chaines de 11400 caractères
    ... a mon avis cette fonction est plus lente que les autres du fait qu'elle n'utilise pas de constantes de précalcul et que l'opération Ord(Val1[i]) passe par un appel indicé au lieu d'utiliser un PChar.

    Mon message suivant portera sur ceux que vous avez postés à partir d'hier d'après 18 heures pour lesquels je vous remercie.
    Le temps de les tester et je reviens.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  3. #23
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    Eric Boisvert a écrit (message d'Hier 19h56) :
    fallait plutot comparer avec:
    For i := 0 To NbrCall Do
    begin
    AdditionProc(s1, s2, len);
    srep:=s2;
    end;
    ... effectivement, et j'en ai vite tenu compte pour les temps que j'ai indiqués dans mon message précédent, par contre en supprimant la ligne srep:=s2 on diviserait les temps d'exécution presque par deux, dommage.

    Eric Boisvert a écrit :
    nous avons effectivement un petit gain tout de même grace à SJR
    en remplacant StringOfChar par SetLength.
    La plus rapide demeure donc celle-ci avec les Array Simplifiés par Anapurna (J'ignore comment fait delphi... mais ca change pas grand chose pour la vitesse et c'est plus jolie!)
    ... globalement oui.
    Eric Boisvert a écrit :
    Mais je me demande pourquoi la AdditionProc n'est pas plus rapide.?.?
    l'optimisation de delphi est vraiment surprenante!!
    ... AdditionProc est en elle-même la plus rapide sauf que son utilisation nécessite la ligne srep:=s2; et je suppose qu'avant d'affecter la chaine s2 à srep Delphi ou Windows est obligé d'allouer de l'espace-mémoire à srep avant cette affectation.
    ... Pour ce qui est de l'optimisation de Delphi c'est effectivement surprenant vu qu'elle augmente la vitesse d'exécution dans notre cas et dans un rapport de 9.22/3.37 = 2,7 pour Addition2EBVbis (chez moi l'optimisation est cochée une fois pour toutes)

    Anapurna a écrit dans son code (message d'Hier 22h33) :
    retenue := byte(offset>= 109);
    ... il faut remplacer par retenue := byte(offset>= 106); sinon erreur de report.

    Comparatif entre la fonction Addition2EBVbis(Const s1: String; Const s2: String; Len: Cardinal): String du 2 aout 19h56 d'Eric Boisvert et celle de même nom du 2aout 22h33 d'Anapurna avec Pentium III 1,13 Ghz et pour NbrCall = 100000 :
    1) version d'Eric Boisvert :
    - mis 142 ms pour chaînes de 128 caractères
    - mis 199 ms pour chaînes de 228 caractères
    - mis 7277 ms pour chaînes de 11400 caractères
    2) version d'Anapurna :
    - mis 218 ms pour chaînes de 128 caractères (1,53 fois plus lent)
    - mis 334 ms pour chaînes de 228 caractères (1,67 fois plus lent)
    - mis 13971 ms pour chaînes de 11400 caractères (1,92 fois plus lent)
    ... or comme il se trouve que la seule différence entre ces deux fonction se situe au niveau de la détermination de la retenue :
    - retenue := PreCalcRet[offset]; dans la version d'Eric Boisvert
    - retenue := byte(offset>= 106); dans la version d'Anapurna
    on peut constater ici l'intérêt de la constante de précalcul ... et les écarts augmentent avec la longueur des chaines.

    Sur ce je vais voir si on ne peut pas encore gratter quelque chose.

    A+

    EDIT : En final je n'ai pas réussi à gratter encore qq millisec.
    Conclusion : à ce jour c'est la fonction Addition2EBVbis(Const s1: String; Const s2: String; Len: Cardinal): String du 2 aout 19h56 d'Eric Boisvert qui est la plus rapide.

    En tous cas merci mille fois pour votre aide.

    Je ne mets pas encore le Tag "Résolu" pour le cas où quelqu'un touverait encore un moyen d'améliorer. Cela donnerait quoi de transformer par exemple la solution d'Eric en code Asm ?

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #24
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    il y a un erreur la fonction ne donne pas le bon calcul

  5. #25
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    je ne voulait pas que la discussion remonte jusqu'ici mais je voulait signaler cet erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      712518543152
    + 856985587519
    = 569504130671

  6. #26
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    C'est pourquoi les chaines d'entrées doivent commencer par 0...
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour
    A cet effet les chaînes envoyées en entrée sont des chaînes calibrées de même longueur et commençant par au moins un ‘0’
    donc...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      0712518543152
    + 0856985587519
    = 1569504130671
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  7. #27
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Probleme de retenue
    essaie
    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
    function Somme(a,b:string;c:Pointer) :integer ; register
    asm
          push ebx
          push esi
          mov ebx,[eax]-4
          mov esi,eax
          xor eax,eax
    @boucle:
          mov al,ah
          xor ah,ah
          add al,byte ptr[esi]
          add al,byte ptr[edx]
          sub ax,$60  //DAS
          cmp al,10   //aaa
          jnae @suite
          sub al,10
          mov ah,1
    @suite:
          or al,$30
          mov byte ptr[ecx],al
          inc esi
          inc edx
          inc ecx
          dec ebx
          jnz @boucle
          or ah,$30
          mov byte ptr[ecx],ah
          pop esi
          pop ebx
    end ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      h1:='712512543152';
      h2:='856984587519';
      h3:=StringOfChar(' ',Length(h1)+1);
      Somme(h1,h2,@h3[1]);

  8. #28
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 862
    Points : 11 321
    Points
    11 321
    Billets dans le blog
    6
    Par défaut
    pour les férus de vitesse, il existe une unité - au développement de laquelle Gilbert Geyer a participé - disponible ici : http://www.phidels.com/php/index.php...ip.php3&id=617
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  9. #29
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Tiens je n'avais pas remarqué que cette discussion, interrompue il y a 2 ans, avait repris.

    J'en profite pour signaler que l'unité citée par Tourlourou "pour les férus de vitesse" permet en plus de franchir allègrement la barrière des 20 chiffres sigificatifs vu qu'elle manipule des strings numériques codées en base 256, et qui dit "string" dit capacité théorique maximale de 2 Go de chiffres significatifs pour chaque nombre : de quoi prendre le vertige :

    Pour fixer les idées, une telle string imprimée recto-verso sur des feuilles A4 avec marges de 2,5 cm en Arial 10 normal (10856 caractères par feuille) nécessiterait l'utilisation de 395,6 paquets de 500 feuilles A4 et comme un seul paquet est épais de 5 cm cela repésente une pile de papier de presque 20 mètres de haut !!!. (un immeuble de 7 étages)

    En bref avec nos bécanes poussives il est impossible d'exploiter à fond les capacités de l'unit : faudrait un Cray pour les exploiter à fond.

    Cordialement et à +.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

Discussions similaires

  1. Nombres de chiffres significatif avec fortran
    Par VauRDeC dans le forum Fortran
    Réponses: 7
    Dernier message: 09/06/2012, 03h42
  2. Problème avec if .. else if.. else dans une fonction
    Par marwa21 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 21/04/2011, 10h37
  3. chiffres significatifs avec plot
    Par Pierre13Th dans le forum MATLAB
    Réponses: 2
    Dernier message: 31/05/2009, 20h24
  4. Nombres de chiffre significatifs sur une figure
    Par lanfou dans le forum MATLAB
    Réponses: 4
    Dernier message: 04/06/2008, 11h36
  5. Réponses: 3
    Dernier message: 07/05/2008, 13h30

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