Fonction HexaToDecimal()

Pour discuter de l'assembleur
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

j'ai lancé ton code et j'ai la même valeur pour les 2 codes, 2280.
je trouve la même chose (2280) avec le debugger, ça serait bien si tu refaisais le test sans le debugger :D
sinon tu peux pas obtenir des cycles d'horloge correcte...
J'ai refait des tests et je me suis rendu compte que je n'avais pas désactivé le débugger
apparemment c'est une manie chez toi :lol: :lol: :lol:
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

erix14 a écrit :
j'ai lancé ton code et j'ai la même valeur pour les 2 codes, 2280.
je trouve la même chose (2280) avec le debugger, ça serait bien si tu refaisais le test sans le debugger :D
sinon tu peux pas obtenir des cycles d'horloge correcte...
J'ai refait des tests et je me suis rendu compte que je n'avais pas désactivé le débugger
apparemment c'est une manie chez toi :lol: :lol: :lol:
Je ne carbure qu'au débugger :D

Sans 60 et 52.

Comme je l'ai écrit

Code : Tout sélectionner

ADD  edx, edx
LEA edx, [(edx*8)+eax] 


l'instruction LEA dans ce cas ne peut pas prendre un cycle, on va avoir une pénalité de 1 cycle du au fait que le registre edx qui se trouve dans le 1er pipeline (edx est utilisé dans l'instruction imméditement avant le LEA) n'a pas encore son résultat de calculé, le pileline V doit attendre un cycle que edx soit calculé.

J'ai modifié le code pour LEA en mettant une instruction de plus, dis-moi combien tu trouves ? (moins de temps avec une instructuion de plus ! ?)

Code : Tout sélectionner

Structure LL
          Low.l
          High.l
EndStructure

Global Debut.LL,Fin.LL,CyclesHorlogeAVide.l,CyclesHorloge1.l,CyclesHorloge2.l,CyclesHorlogeTemp.l

CyclesHorlogeAVide = 999999999
CyclesHorloge1 = 999999999
CyclesHorloge2 = 999999999

MOV ecx,100000
!EncoreCycles:

!RDTSC
MOV Debut\Low, eax
MOV Debut\High, edx
!RDTSC
MOV Fin\Low, eax
MOV Fin\High, edx
!fild qword [v_Fin]
!fild qword [v_Debut]
!fsubp
!fistp dword[v_CyclesHorlogeTemp]
If CyclesHorlogeTemp < CyclesHorlogeAVide
          CyclesHorlogeAVide = CyclesHorlogeTemp
EndIf

!RDTSC
MOV Debut\Low, eax
MOV Debut\High, edx
;/        code 1

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

ROL edx,4
ADD edx,eax

;/        fin code 1
!RDTSC
MOV Fin\Low, eax
MOV Fin\High, edx
!fild qword [v_Fin]
!fild qword [v_Debut]
!fsubp
!fistp dword[v_CyclesHorlogeTemp]
If CyclesHorlogeTemp < CyclesHorloge1
          CyclesHorloge1 = CyclesHorlogeTemp
EndIf

!RDTSC
MOV Debut\Low, eax
MOV Debut\High, edx
;/        code 2


ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

ADD  edx, edx
NOP
LEA edx, [(edx*8)+eax]

;/        fin code 2
!RDTSC
MOV Fin\Low, eax
MOV Fin\High, edx
!fild qword [v_Fin]
!fild qword [v_Debut]
!fsubp
!fistp dword[v_CyclesHorlogeTemp]
If CyclesHorlogeTemp < CyclesHorloge2
          CyclesHorloge2 = CyclesHorlogeTemp
EndIf

DEC ecx
JNZ EncoreCycles

message$ = "Cycles d'horloge code 1 : " + Str(CyclesHorloge1-CyclesHorlogeAVide) + Space(20) + Chr(13)
message$ = message$ + "Cycles d'horloge code 2 : " + Str(CyclesHorloge2-CyclesHorlogeAVide) + Chr(13)
MessageRequester("Vitesse ASM", message$, #MB_ICONINFORMATION)
on ne peut pas faire directement une multiplication par 16 avec LEA, mais par 8 oui, essaye ce code qui fait la même chose


Code : Tout sélectionner

Structure LL
          Low.l
          High.l
EndStructure

Global Debut.LL,Fin.LL,CyclesHorlogeAVide.l,CyclesHorloge1.l,CyclesHorloge2.l,CyclesHorlogeTemp.l

CyclesHorlogeAVide = 999999999
CyclesHorloge1 = 999999999
CyclesHorloge2 = 999999999

MOV ecx,100000
!EncoreCycles:

!RDTSC
MOV Debut\Low, eax
MOV Debut\High, edx
!RDTSC
MOV Fin\Low, eax
MOV Fin\High, edx
!fild qword [v_Fin]
!fild qword [v_Debut]
!fsubp
!fistp dword[v_CyclesHorlogeTemp]
If CyclesHorlogeTemp < CyclesHorlogeAVide
          CyclesHorlogeAVide = CyclesHorlogeTemp
EndIf

!RDTSC
MOV Debut\Low, eax
MOV Debut\High, edx
;/        code 1
; PUSHAD; CallDebugger; POPAD
ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

ROL edx,3
ADD edx,eax

;/        fin code 1
!RDTSC
MOV Fin\Low, eax
MOV Fin\High, edx
!fild qword [v_Fin]
!fild qword [v_Debut]
!fsubp
!fistp dword[v_CyclesHorlogeTemp]
If CyclesHorlogeTemp < CyclesHorloge1
          CyclesHorloge1 = CyclesHorlogeTemp
EndIf

!RDTSC
MOV Debut\Low, eax
MOV Debut\High, edx
;/        code 2

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

LEA edx, [(edx*8)+eax]

;/        fin code 2
!RDTSC
MOV Fin\Low, eax
MOV Fin\High, edx
!fild qword [v_Fin]
!fild qword [v_Debut]
!fsubp
!fistp dword[v_CyclesHorlogeTemp]
If CyclesHorlogeTemp < CyclesHorloge2
          CyclesHorloge2 = CyclesHorlogeTemp
EndIf

DEC ecx
JNZ EncoreCycles

message$ = "Cycles d'horloge code 1 : " + Str(CyclesHorloge1-CyclesHorlogeAVide) + Space(20) + Chr(13)
message$ = message$ + "Cycles d'horloge code 2 : " + Str(CyclesHorloge2-CyclesHorlogeAVide) + Chr(13)
MessageRequester("Vitesse ASM", message$, #MB_ICONINFORMATION)
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

le 1er code : 60 et 48

Merci pour l'info Denis, avec une instruction de plus ( NOP ) on va plus vite que sans le NOP ( c'est génial !!!! ) :D

le 2eme code : 60 et 40
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

erix14 a écrit :le 1er code : 60 et 48

Merci pour l'info Denis, avec une instruction de plus ( NOP ) on va plus vite que sans le NOP ( c'est génial !!!! ) :D

le 2eme code : 60 et 40
C'est surement une des raisons pour lesquelles on ne trouve pas vraiment les cycles pour les instructions, ça dépend de la prédiction d'instruction.

Il me semble avoir lu que l'AGI est expliqué dans un des manuels d'intel, celui-ci je crois

IA-32 Intel Architecture Optimization Reference Manual .pdf
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Je vais faire une lib avec les 2 fonctions hexatodeci et bintodeci.
Ca sera plus rapide que la version PB (quelques cycles)
Quel noms proposez-vous pour ces 2 fonctions et quel nom pour la lib ?

Faut-il tester la présence du signe $ et du % ou alors on peut coder 4 fonctions avec variantes tests sur le $ et % et sans (?)

Quelqu'un veut faire les 2(4) fichiers html de la doc ?, je n'aurais plus qu'a faire le chm :D


vous voyez d'autres fonctions pour cette lib ?
A+
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Code : Tout sélectionner

Procedure.f pi()
 !FLDPI
EndProcedure

Code : Tout sélectionner

Procedure.f Atan2(y.f, x.f)
 FLD y      ;Get y onto the FPU stack
 FLD x      ;Get x onto the FPU stack 
 FPATAN     ;Get the ATAN(y/x), Put result in ST(1) then pop the stack 
 
 ;!fstp dword [esp+8] ;pas besoin, pure renvoie la dernière valeur st(0)
 ;ProcedureReturn retour
 
EndProcedure

Code : Tout sélectionner

Procedure.f radians(angle.f)
 ProcedureReturn (angle*2*#PI)/360
EndProcedure

Code : Tout sélectionner

Procedure.f degrees(angle.f)
 ProcedureReturn (angle*360)/(2*#PI)
EndProcedure
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Fonction HexaToDecimal()

Message par PAPIPP »

Bonjour à tous
Je déterre ce post de 2005 car depuis il y a eu des améliorations.
Tout d’abord merci aux anciens qui ne viennent plus très souvent sur le forum Erix14 Denis et aux deux autres encore là djes et LSI
Dans un premier temps je me suis limité aux conversions sur un octet pour deux raisons.
La première raison est donnée par les tests qui suivent.
La deuxième est purement logique.
En effet lorsque l’on dumpe une mémoire ou un fichier il est assez rare que l’on connaisse parfaitement la structure de la zone dumpée. Or intel code ses nombres en little indian.
Ce qui ne correspond pas à l’ordre croissant des poids des nombres et des adresses croissantes.
Un exemple ci-dessous vous fera comprendre la différence

Code : Tout sélectionner

ProcedureDLL.s _m_h(ad,lng,flag.b)
  ;   Static flag0.b
  Protected i.l,hex.s,cart$,sort.s
  ;   flag0=flag0-flag
  If flag>0
    ; ;     TETH.s="adresse    0                                               1                                               2                                               3                                               4   "+#LF$
    ; ;     sort.s=Left(teth,(lng-1)*3+12)+"    ASCII"+#LF$
    ; ;     teth.s=" Unité     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1"+#LF$
    teth.s="Adresse___00_01_02_03_04_05_06_07_08_09_0A_0B_0C_0D_0E_0F_10_11_12_13_14_15_16_17_18_19_1A_1B_1C_1D_1E_1F_20_21_22_23_24_25_26_27_28_29_2A_2B_2C_2D_2E_2F_30_31_32_33_34_35_36_37_38_39_3A_3B_3C_3D_3E_3F_40_41"
    sort.s+Left(teth,(lng-1)*3+12)+"        ASCII"
    
    If flag =1
      sort.s+#LF$
    Else
      ProcedureReturn sort
    EndIf
    flag0=1
  EndIf
  For i=0 To lng-1
    num.c=PeekC(ad+i)
    If Chr(num)<" "
      cart$=cart$+"."
    Else
      cart$=cart$+Chr(num)
    EndIf
    hexs.s=hexs.s+RSet(Hex(num),2,"0")+"_"
  Next
  sort.s+RSet(Hex(ad),8,"0")+"  "+hexs+"    "+cart$+#LF$
  ProcedureReturn sort
EndProcedure
VA.A=$12
VW.W=$1234
VL.l=$12345678
VQ.q=$1234567890123456
VS.s{20}="Durand jean-Paul"
Debug Hex(VA,#PB_Byte)
Debug _m_h(@VA,4,2)
Debug _m_h(@VA,4,0)
; Debug Hex(VA,#PB_Ascii)
Debug Hex(VW,#PB_Word) 
Debug _m_h(@VW,4,2)
Debug _m_h(@Vw,4,0)
Debug Hex(VL,#PB_Long )
Debug _m_h(@VL,4,2)
Debug _m_h(@VL,4,0)
Debug Hex(VQ,#PB_Quad     )
Debug _m_h(@VQ,8,2)
Debug _m_h(@VQ,8,0)
;************************* A partir d'ici les caratères type string sont placés dans l'ordre du plus faible à gauche au plus fort à droite
s$=""
For i=0 To 20
S$+Hex(PeekC(i+@VS))+"-"
Next
Debug s$
Debug _m_h(@VS,32,2)
Debug _m_h(@VS,32,0)
PokeS(12+@VS,Chr(00),1)
Debug VS
Debug _m_h(@VS,32,2)
Debug _m_h(@VS,32,0)
VS2.s{20}=VS.s{20}
Debug VS2
Debug _m_h(@VS2,32,2)
Debug _m_h(@VS2,32,0)
CopyMemory(@VS,@VS2,20)
Debug VS2
Debug _m_h(@VS2,32,2)
Debug _m_h(@VS2,32,0)
L’argument principal de ce post vient des tests effectués aujourd’hui et qui confirme 2 méthodes beaucoup plus rapides que les 2 prg ASM
Pour le fun j’ai codé moi-même un PRG en ASM, mais s’il est un peu plus rapide que ceux de 2005 il est loin de concurrencer les 2 autres méthodes
Voici les prg et les tests.

Code : Tout sélectionner

Structure EL_h
  Bn.s{8}
  Hx.s{2}
  StructureUnion
    VA.a   ; ascii
    VB.b   ; byte
    VC.c   ; character
    VS.s{1}; String 1 Byte
  EndStructureUnion
EndStructure
Structure tab_H
  Array el.el_H(256)
EndStructure
Global NewMap mp256.EL_H()
Global NewMap mp256b.EL_H() ; Pour obtenir des temps inférieures à la méthode classique val($xx) la map des binaires a été sortie
Global TAB.tab_h

ProcedureDLL.q __nbcs() ;**** Procédure pour évaluer le nb de cycles machine
  !RDTSC
  ProcedureReturn
EndProcedure
Procedure ValHex(Chaine.s) ;de Erix14  Denis LSI
  Valeur.l
  MOV ecx,Chaine
  CMP byte[ecx],'$'
  JNZ NonChaineHexa
  !LEA ebx,[TableValeur]
  MOV edx,0
  XOR eax,eax
  !Encore:
  INC ecx
  MOV al,byte[ecx]
  CMP al,0
  JE FinChaineHexa
  XLATB
  CMP al,$FF
  JE NonChaineHexa
  ROL edx,4
  ADD edx,eax
  JMP Encore
  !FinChaineHexa:
  MOV Valeur,edx
  ProcedureReturn Valeur
  !NonChaineHexa:
  ProcedureReturn 0
  !TableValeur:
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$0A,$0B,$0C,$0D,$0E,$0F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$0A,$0B,$0C,$0D,$0E,$0F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
EndProcedure
;
Procedure ValHex1(Chaine.s) ;de Erix14  Denis LSI
  Valeur.l
  MOV ecx,Chaine
  CMP byte[ecx],'$'
  JNZ NonChaineHexa1
  !LEA ebx,[TableValeur1]
  MOV edx,0
  XOR eax,eax
  !Encore1:
  INC ecx
  MOV al,byte[ecx]
  CMP al,0
  JE FinChaineHexa1
  XLATB
  ADD edx,edx
  CMP al,$FF
  JE NonChaineHexa1
  LEA edx, [edx*8+eax]
  ; ROL edx,4
  ; ADD edx,eax
  JMP Encore
  !FinChaineHexa1:
  MOV Valeur,edx
  ProcedureReturn Valeur
  !NonChaineHexa1:
  ProcedureReturn 0
  !TableValeur1:
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$0A,$0B,$0C,$0D,$0E,$0F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$0A,$0B,$0C,$0D,$0E,$0F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
EndProcedure

Procedure.a CONV_HEX_CODM(HEX1.s) ;***** ici on passe la valeur de l'octet ******
  ; p.v_HEX1 equ esp+PS0+0 si HEX1
  ; p.p_HEX1 equ esp+PS0+0 si *HEX1
  ; p.v_VL equ esp+0
  Protected VL.a
  !LEA ebx,[P_Tab_Val_b]     ; Charge l'adresse de la table de conversion necessaire à l'instruction XLATB
  !xor edx,edx               ; 0 dans EAX
  !MOV	ebp,dword [p.v_HEX1]
  !MOVZX	eax,byte [ebp+1]   ; Charge bit de plus fort poids
  !sub al,$30                ; Soutraire $30 ou 48 decimal pour obtenir l'offset de la table de conversion
  !XLATB                     ; Remplace la valeur de AL offset pour la table par la valeur trouvée dans la table adresse en EBX résultat dans AL
  !MOV DL,al                 ; Sauvegarde de AL dans DL partie Basse de DX
  !MOVZX	eax,byte [ebp]    ; Charge bit de plus faible poids
  !sub al,$30                ; Soutraire $30 ou 48 decimal pour obtenir l'offset de la table de conversion
  !XLATB                     ; Remplace la valeur de AL offset pour la table par la valeur trouvée dans la table adresse en EBX résultat dans AL
  !SHL AX,4                  ; décalage vers la gauche de 4 bits donc multiplication par 16
  !add dx,ax                 ;:Addition du poids faible et du poids fort dans DX
  !MOV [p.v_VL],dx           ; Passage de la valeur Bin  dans VL et passage en retour de PRG
  ProcedureReturn VL
  !P_Tab_Val_b:              ;; Table de conversion d'Hexa en Binaire ou code machine
  ! DB $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$FF,7 dup $FF,$0A,$0B,$0C,$0D,$0E,$0F, 240 dup ($FF)
EndProcedure
Procedure.l CHARG_TAB_MAP(FL.b)
 ;  si FL=1 chargement de la table seule si FL= 2 chargement de la map mp256 (hex) si FL =4 chargement de la map mp256p (bin)
 ;  si F1 = 3 chargement de la table et de la map mp256 seulemet si FL=5 charment de la Table et de la map mp256b (bin)
 ;  si FL=6 chargement de map256 (hex) et de la map mp256p (bin) si FL=7 chargement de la table et des deux MAp
  Static flag.b=0; ,*adrs.S_x_cr,*sort.S_x_cr
  Protected _ii.i;,typ${1}="",rmp${1}="",pref${1}="",ret_xx.s="",
  If flag=0 ; passe ici une seule fois au premier appel
    ; ** Chargement de la table en accés direct
    For _ii=0 To 255
      If Fl= 1 Or 3 Or 5 Or 7 ; chargement de table acces direct 
        tab\el(_ii)\bn=RSet(Bin(_ii,#PB_Ascii),8,"0")
        tab\el(_ii)\Hx=RSet(Hex(_ii,#PB_Ascii),2,"0")
        ;       tab\el(_ii)\Hx=CONV_DEC_HEX(_ii) ; Utilisable si CONV_DEC_HEX() est présent plus rapide que hex() 
        ;       tab\el(_ii)\VA=_ii
        ;**** Essai d'utilisation d'une map pour convertir bin en Hexa ou en bin expensé moins rapide que la table à accés direct ******
        ;       AddMapElement(mp256(),Chr(_ii))
        ;       mp256()\Bn=tab\el(_ii)\bn
        ;       mp256()\Hx=tab\el(_ii)\Hx
        ;       mp256()\VA=_ii
      EndIf  
      If FL=2 Or 4
        AddMapElement(mp256(),RSet(Hex(_ii,#PB_Ascii),2,"0"))
        mp256()\Bn=RSet(Bin(_ii,#PB_Ascii),8,"0")
        mp256()\Hx=RSet(Hex(_ii,#PB_Ascii),2,"0")
        mp256()\VA=_ii
      EndIf 
      If FL=3 Or 7 
        AddMapElement(mp256(),tab\el(_ii)\Hx)
        mp256()\Bn=tab\el(_ii)\bn
        mp256()\Hx=tab\el(_ii)\Hx
        mp256()\VA=_ii
      EndIf
      If Fl>3
        AddMapElement(mp256b(),tab\el(_ii)\bn)
        mp256b()\Bn=tab\el(_ii)\bn
        mp256b()\Hx=tab\el(_ii)\Hx
        mp256b()\VA=_ii
      EndIf
    Next
    
    EndIf
  flag+1 ; pour compter le nb d'appels inutils 
  
EndProcedure
; Vq.q=$123456789012345 
; H$=Hex(Vq)
; VALh.q=Valhex("$"+H$)
; Debug vq-VALh ;; ICI ERREUR LES 2 PRG NE DECODENT QUE SUR 4 OCTETS MAX
; Vq.q=$12345678 
; H$=Hex(Vq)
; VALh.q=Valhex("$"+H$)
; Debug vq-VALh
; 
; End
; charg_tab_map(3)
; For i=0 To $FF
;   A$=RSet(Hex(i),2,"0")
;       FindMapElement(Mp256(),A$)
;       val00=mp256()\VA
;   Debug _n(val00)+_n(I)+_s(A$)
;   Next

;   For i=0 To 255
;     A$=RSet(Hex(i),2,"0")
;     val0=Val("$"+A$)
;   Debug _n(val0)+_n(I)+_s(A$)
;   Next

; For i=0 To 255
;   A$=RSet(Hex(i),2,"0")
;   val=ValHEX("$"+A$)
;   Debug _n(val)+_n(I)+_s(A$)
; Next
; For i=0 To 255
;   A$=RSet(Hex(i),2,"0")
;   Debug _n(CONV_HEX_CODM(A$))+_n(I)+_s(A$)
; Next
; End
;*************************************************************************************************
resultat$=""
SetPriorityClass_(GetCurrentProcess_(),#HIGH_PRIORITY_CLASS)


BMAX=20000
Hmin=0
Hmax=$FF  ; Vous pouvez tester les prg sur 4 octets mais 2 methodes ne sont codées que sur un octet
RESULTAT$+" CONDITIONS ==>: BMAX="+Str(BMAX)+" Hmin="+Str(Hmin)+" Hmax="+Str(Hmax)+#CRLF$
D1.q=__nbcs()
De1=ElapsedMilliseconds()
charg_tab_map(3)
resultat$+"Chargement de la table:"+Str(__nbcs()-D1)+#CRLF$+"Temps elapse ="+Str(ElapsedMilliseconds()-De1)+#CRLF$
DUR0.q=ElapsedMilliseconds()-De1

D1.q=__nbcs()
De1=ElapsedMilliseconds()
For j=0 To BMAX
  For i=hmin To Hmax
    A$=RSet(Hex(i),4,"0")
    val.a=Val("$"+A$)
  Next
Next
resultat$+"val=Val('$'+A$):"+Str(__nbcs()-D1)+#CRLF$+"Temps elapse ="+Str(ElapsedMilliseconds()-De1)+#CRLF$
DUR1.q=ElapsedMilliseconds()-De1

D1.q=__nbcs()
De1=ElapsedMilliseconds()

For j=0 To BMAX
  For i=hmin To Hmax
    A$=RSet(Hex(i),4,"0")
    val.a=ValHEX("$"+A$)
  Next
Next
resultat$+"ValHEX('$'+A$):"+Str(__nbcs()-D1)+#CRLF$+"Temps elapse ="+Str(ElapsedMilliseconds()-De1)+#CRLF$
DUR2.q=ElapsedMilliseconds()-De1

D1.q=__nbcs()
De1=ElapsedMilliseconds()

For j=0 To BMAX
  For i=hmin To Hmax
    A$=RSet(Hex(i),4,"0")
    val.a=ValHEX1("$"+A$)
  Next
Next
resultat$+"ValHEX1('$'+A$):"+Str(__nbcs()-D1)+#CRLF$+"Temps elapse ="+Str(ElapsedMilliseconds()-De1)+#CRLF$
DUR3.q=ElapsedMilliseconds()-De1

D1.q=__nbcs()
De1=ElapsedMilliseconds()
For j=0 To BMAX
  For i=hmin To Hmax
    A$=RSet(Hex(i),2,"0")
    val.a=CONV_HEX_CODM(A$)
  Next
Next
resultat$+"CONV_HEX_CODM(A$):"+Str(__nbcs()-D1)+#CRLF$+"Temps elapse ="+Str(ElapsedMilliseconds()-De1)+#CRLF$
DUR4.q=ElapsedMilliseconds()-De1

D1.q=__nbcs()
De1=ElapsedMilliseconds()
For j=0 To BMAX
  For i=hmin To Hmax
    A$=RSet(Hex(i),2,"0")
    FindMapElement(Mp256(),A$)
    val.a=mp256()\VA
  Next
Next
resultat$+"FindMapElement(Mp256(),A$):"+Str(__nbcs()-D1)+#CRLF$+"Temps elapse ="+Str(ElapsedMilliseconds()-De1)+#CRLF$
DUR5.q=ElapsedMilliseconds()-De1

D1.q=__nbcs()
De1=ElapsedMilliseconds()
For j=0 To BMAX
  For i=hmin To Hmax
    A$=RSet(Hex(i),2,"0")
    ;   RIEN afin de décompter le temps de la boucle et de ne garder que le temps des instructions utiles
  Next
Next
resultat$+"sans rien:"+Str(__nbcs()-D1)+#CRLF$+Str(ElapsedMilliseconds()-De1)+#CRLF$
DURdur.q=ElapsedMilliseconds()-De1

resultat$+" Temps réel de val()="+Str(DUR1-DURDUR)+#CRLF$
resultat$+" Temps réel de VALHEX()="+Str(DUR2-DURDUR)+#CRLF$
resultat$+" Temps réel de VALHEX1()="+Str(DUR3-DURDUR)+#CRLF$
resultat$+" Temps réel de CONV_HEX_CODM="+Str(DUR4-DURDUR)+#CRLF$
resultat$+" Temps réel de FindMapElement(Mp256()="+Str(DUR5-DURDUR)+#CRLF$

MessageRequester("ATTENTION",resultat$)
CreateFile(00,"C:\RESUL_conv_hex_bin.txt")
WriteData(00,@resultat$,Len(resultat$))
CloseFile(00)
Un fichier "C:\RESUL_conv_hex_bin.txt" vous donne les résultats en txt ,ils peuvent être donné ici
CONDITIONS ==>: BMAX=20000 Hmin=0 Hmax=255
Chargement de la table:1262320
Temps elapse =0
val=Val('$'+A$):7025226728
Temps elapse =2188
ValHEX('$'+A$):10785781784
Temps elapse =3390
ValHEX1('$'+A$):10894674624
Temps elapse =3407
CONV_HEX_CODM(A$):9002757632
Temps elapse =2828
FindMapElement(Mp256(),A$):6292139776
Temps elapse =1968
sans rien:5605571808
1750
Temps réel de val()=438
Temps réel de VALHEX()=1640
Temps réel de VALHEX1()=1657
Temps réel de CONV_HEX_CODM=1078
Temps réel de FindMapElement(Mp256()=218
Les 2 programmes valhex() et valhex1() ne convertissent que les type .l 4 octets mais pas les types .q 8 octets non connus en 2005 dans PB (Voir tests en commentaire)
Pour les résultats deux remarques :
1) l'instruction VAL() est nettement plus rapide que les programmes ASM et donne la possibilité de convertir jusqu'à 8 octets type .q
2) la méthode d'une table exploitée avec map() est la solution la plus rapide.

Pouvez vous me confirmer les résultats obtenus ici merci d'avance.
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: Fonction HexaToDecimal()

Message par Mesa »

Voici mon résultat avec un "vieux" pentium 4 monocore (netburst) + xp32b
CONDITIONS ==>: BMAX=20000 Hmin=0 Hmax=255
Chargement de la table:8193294
Temps elapse =0
val=Val('$'+A$):10965787848
Temps elapse =3922
ValHEX('$'+A$):59776957448
Temps elapse =21360
ValHEX1('$'+A$):59975692712
Temps elapse =21453
CONV_HEX_CODM(A$):23637031680
Temps elapse =8437
FindMapElement(Mp256(),A$):11662005832
Temps elapse =4172
sans rien:10162577028
3641
Temps réel de val()=281
Temps réel de VALHEX()=17719
Temps réel de VALHEX1()=17812
Temps réel de CONV_HEX_CODM=4796
Temps réel de FindMapElement(Mp256()=531
Mesa.
Répondre