J'ai un AMD Athlon 1,4Ghzerix14 a écrit :..A moins que tu n'es effectivement pas de SSE
Tu as quoi comme microprocesseur ?
Librairie pour optimisation
Cool, Pour une fois qu'un code marche mieux sur mon pentium 4 que sur un AMD
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je viens de réaliser une nouvelle version de la librairie (à télécharger sur mon site RX14). Maintenant, on peut connaître le rapport de vitesse à partir d'un test de référence (voir les explications de Flype quelques messages avant). La méthode Display a maintenant un paramètre pour indiquer le test à prendre en référence. Et pour avoir le calcul le plus juste possible, il faut retrancher le nombre de cycles « à vide », cette valeur est passée par la fonction New_Test(NombreCyclesAVide). C'est à chacun de régler cette valeur, car elle est certainement différente pour chaque configuration. J'ai aussi ajouté l'envoi automatique des résultats dans le presse-papier pour faciliter la diffusion sur le forum, il y a en entête la configuration de l'ordi. Voici un autre petit exemple, l'optimisation de la fonction Mid(), codée par Trond.
Code : Tout sélectionner
Macro Mid2(String, StartPos, length)
MidAscii(@String, StartPos, length)
EndMacro
Procedure.s MidAscii(String, StartPos, Longueur)
; Codé par Trond
!MOV Eax, [p.v_String]
!ADD Eax, [p.v_StartPos]
!DEC Eax
!MOV Edx, Eax
!ADD Eax, [p.v_Longueur]
!MOV cl, byte [Eax]
!PUSH Ecx
!MOV byte [Eax], 0
!MOV Ebx, Eax
!PUSH dword [_PB_StringBasePosition]
!CALL _SYS_CopyString@0
!POP Eax
!ADD Eax, [PB_StringBase]
!POP Ecx
!MOV byte [Ebx], cl
ProcedureReturn
ProcedureReturn ""
EndProcedure
TailleChaine = 30
VeryLongString.s = Space(TailleChaine)+"AAAABBBBCCCCDDDD"
TailleChaine + 5
*Test.ITest = New_Test(256)
For t=0 To #ITest
*Test\Start(1)
Mid(VeryLongString, TailleChaine, 4)
*Test\Stop(1)
Next
*Test\SetTitle(1, "Mid() = "+Mid(VeryLongString, TailleChaine, 4))
For t=0 To #ITest
*Test\Start(2)
Mid2(VeryLongString, TailleChaine, 4)
*Test\Stop(2)
Next
*Test\SetTitle(2, "Mid2() = "+Mid2(VeryLongString, TailleChaine, 4))
For t=0 To #ITest
*Test\Start(3)
; à vide
*Test\Stop(3)
Next
*Test\SetTitle(3, "Test à vide")
*Test\Display(1)
Comme j'ai utilisé ma classe WMI et qu'elle est incluse dans la librairie, voici un exemple d'utilisation :Intel(R) Pentium(R) 4 CPU 2.40GHz
2.43 GHz, 768Mo de RAM
NVIDIA GeForce4 Ti 4800 SE - 128Mo
Microsoft Windows XP Professionnel Service Pack 2
-----------------------------------
Mid() = BBBB
480 cycles CPU (minimum)
530 cycles en moyenne
X 1.00
-----------------------------------
Mid2() = BBBB
240 cycles CPU (minimum)
302 cycles en moyenne
X 2.00
-----------------------------------
Test à vide
0 cycles CPU (minimum)
20 cycles en moyenne
X ???
-----------------------------------
Code : Tout sélectionner
Global WMI.IWMI = New_WMI()
If WMI\ExecQuery("Select Name,CurrentClockSpeed from Win32_Processor") = #S_OK
Debug WMI\GetS("Name") + " ( " + StrF(WMI\GetL("CurrentClockSpeed")/1000, 2) + " GHz )"
WMI\ReleaseQuery()
EndIf
If WMI\ExecQuery("SELECT Name,AdapterRAM FROM Win32_VideoController") = #S_OK
Debug WMI\GetS("Name") + " - " + Str(WMI\GetL("AdapterRAM")/$100000)+"Mo"
WMI\ReleaseQuery()
EndIf
If WMI\ExecQuery("Select Caption,CSDVersion from Win32_OperatingSystem") = #S_OK
Debug WMI\GetS("Caption") + " " + WMI\GetS("CSDVersion")
WMI\ReleaseQuery()
EndIf
Franchement c'est génial. Merci erix14. c'est bon je m'en sers à donf maintenant.
Par contre j'ai du mal avec la valeur d'init du constructeur (new).
j'ai pas tout compris en fait. si je mets 256 çà va, mais certaines valeurs font carrément planter le graphique (tout blanc ou rien) et puis je vois comment à sûr de la valeur à mettre.
Aussi, j'ai un gros plantage si j'essaye d'utiliser plusieurs fois la fonction Display() - je veux dire si je fais une 1ere serie de test, puis une 2eme dans le même source...
Stp, y a-t-il moyen d'avoir le source pour le WMI - çà m'intéresse bcp ?
par contre c'est pas compatible Win98 c'est çà ?
Par contre j'ai du mal avec la valeur d'init du constructeur (new).
j'ai pas tout compris en fait. si je mets 256 çà va, mais certaines valeurs font carrément planter le graphique (tout blanc ou rien) et puis je vois comment à sûr de la valeur à mettre.
Aussi, j'ai un gros plantage si j'essaye d'utiliser plusieurs fois la fonction Display() - je veux dire si je fais une 1ere serie de test, puis une 2eme dans le même source...
Stp, y a-t-il moyen d'avoir le source pour le WMI - çà m'intéresse bcp ?
par contre c'est pas compatible Win98 c'est çà ?
@Flype : Je viens de régler le problème du plantage, la nouvelle version est à télécharger toujours au même endroit. Par contre, je n'ai pas réussi à reproduire ton problème du graphique tout blanc. La valeur que tu dois mettre dans le constructeur c'est le nombre de cycles d'horloge à vide. Quand tu réalises des tests, fais-en un toujours à vide pour déterminer cette valeur.
Voici maintenant un autre exemple avec l'optimisation D-loop. il permet de calculer le nombre qu'une même lettre dans une phrase. (n'oubliez pas d'activer l'assembleur en ligne)
Voici maintenant un autre exemple avec l'optimisation D-loop. il permet de calculer le nombre qu'une même lettre dans une phrase. (n'oubliez pas d'activer l'assembleur en ligne)
Code : Tout sélectionner
EnableExplicit
Global t.l, a.l
Procedure Count_Char(*Str.Character, LeChar.c)
Protected NbChar.l
While *Str\c
If *Str\c = LeChar : NbChar + 1 : EndIf
*Str + 1
Wend
ProcedureReturn NbChar
EndProcedure
Global Dim TableauChar.c(256)
TableauChar(0) = 2
Procedure Count_Char_2(*Str.Character, LeChar.c)
Protected NbChar.l
TableauChar(LeChar) = 1
While *Str\c
While TableauChar(*Str\c) = 0
*Str + 1
Wend
If *Str\c = 0 : Break : EndIf
NbChar + 1
*Str + 1
Wend
TableauChar(LeChar) = 0
ProcedureReturn NbChar
EndProcedure
Procedure Count_Char_3(*Str.Character, LeChar.c)
Protected NbChar.l
TableauChar(LeChar) = 1
MOV Ecx,*Str
!MOV Ebx,dword [a_TableauChar]
!XOR Eax,Eax
MOV ah,LeChar
!Encore1:
MOV al,byte [Ecx]
INC Ecx
XLATB
CMP al,0
JE Encore1
CMP al,2
JE FinCountChar
NbChar + 1
JMP Encore1
!FinCountChar:
TableauChar(LeChar) = 0
ProcedureReturn NbChar
EndProcedure
Global MaString.s = "djfqgkjdhfgsjfgjkdnlngld fgsdjfhg dfjh gsdjfg df"
Global MonTest.ITest = New_Test(288)
For t=0 To #ITest
MonTest\Start(1)
a = Count_Char(@MaString, 'd')
MonTest\Stop(1)
Next
MonTest\SetTitle(1, "Méthode traditionnelle : Count_Char() = "+Str(a))
;/
For t=0 To #ITest
MonTest\Start(2)
a = Count_Char_2(@MaString, 'd')
MonTest\Stop(2)
Next
MonTest\SetTitle(2, "Méthode D-loop : Count_Char_2() = "+Str(a))
;/
For t=0 To #ITest
MonTest\Start(3)
a = Count_Char_3(@MaString, 'd')
MonTest\Stop(3)
Next
MonTest\SetTitle(3, "Méthode D-loop ASM : Count_Char_3() = "+Str(a))
;/
For t=0 To #ITest
MonTest\Start(4)
MonTest\Stop(4)
Next
MonTest\SetTitle(4, "A vide")
MonTest\Display(1)
Indiquez-moi vos résultats, je suis curieux de savoir ce que cela donne chez vous et de savoir si tout monde a compris le fonctionnement.Intel(R) Pentium(R) 4 CPU 2.40GHz
2.43 GHz, 768Mo de RAM
NVIDIA GeForce4 Ti 4800 SE - 128Mo
Microsoft Windows XP Professionnel Service Pack 2
-----------------------------------
Méthode traditionnelle : Count_Char() = 8
812 cycles CPU (minimum)
868 cycles en moyenne
X 1.00
-----------------------------------
Méthode D-loop : Count_Char_2() = 8
728 cycles CPU (minimum)
806 cycles en moyenne
X 1.12
-----------------------------------
Méthode D-loop ASM : Count_Char_3() = 8
528 cycles CPU (minimum)
584 cycles en moyenne
X 1.54
-----------------------------------
A vide
0 cycles CPU (minimum)
27 cycles en moyenne
X ???
-----------------------------------
Here is the results for flaith
Processor: AMD Athlon(TM)Processor, ~1.4GHz
Memory: 1024MB RAM
Operating System: Windows 2000 Professional (5.0, Build 2195) Service Pack 4
Card name: NVIDIA GeForce FX 5500 - 128Mo
Current Mode: 1280 x 1024 (32 bit) (85Hz)
-----------------------------------
Méthode traditionnelle : Count_Char() = 8
641 cycles CPU (minimum)
647 cycles en moyenne
X 1.00
-----------------------------------
Méthode D-loop : Count_Char_2() = 8
787 cycles CPU (minimum)
790 cycles en moyenne
X 0.81
-----------------------------------
Méthode D-loop ASM : Count_Char_3() = 8
316 cycles CPU (minimum)
334 cycles en moyenne
X 2.03
-----------------------------------
A vide
0 cycles CPU (minimum)
0 cycles en moyenne
X ???
-----------------------------------
et les miens - merci au fait
et le test à vide ne retourne pas de résultat - donc pas possible d'affiner le new().
intéressant ce D-loop en tout cas.
la commande ASM XLATB fait planter le debugger chez moi (invalid access memory) - un conflit avec le debugger (qui doit lui aussi faire des petits sauts mémoire et des bidouillages de piles ?AMD Athlon(tm) XP 2800+
2.08 GHz, 512Mo de RAM
NVIDIA GeForce 6800 GT - 256Mo
Microsoft Windows XP Professionnel Service Pack 2
-----------------------------------
Méthode traditionnelle : Count_Char() = 8
634 cycles CPU (minimum)
670 cycles en moyenne
X 1.00
-----------------------------------
Méthode D-loop : Count_Char_2() = 8
819 cycles CPU (minimum)
2159 cycles en moyenne
X 0.77
-----------------------------------
Méthode D-loop ASM : Count_Char_3() = 8
383 cycles CPU (minimum)
408 cycles en moyenne
X 1.66
-----------------------------------
A vide
0 cycles CPU (minimum)
0 cycles en moyenne
X ???
-----------------------------------
et le test à vide ne retourne pas de résultat - donc pas possible d'affiner le new().
intéressant ce D-loop en tout cas.
Bien, les résultats sont cohérents entre AMD et Intel. Il y a plus de cycle d'horloge chez Intel, car ils ont privilégié la fréquence... Si une autre personne pouvait faire un test avec un autre Pentium?
Les problèmes de débogueur avec l'assembleur ne sont pas nouveaux, moi qui fais pas mal d'assembleur, c'est la plaie!
Le principe du débogueur c’est :
1) récupérer les erreurs, comme la fonction OnErrorGosub(@Procedure())
2) faire un appel au débogueur entre chaque ligne PureBasic pour suivre l'état des registres, variables, etc. ou faire un arrêt... Le problème, c'est que l'état des registres n'est pas bien restitué au retour du débogueur. XLATB utilise le registre Ebx qui contient l'adresse du tableau, et avec le débogueur Ebx perd cette adresse.
PS : Vous devez mettre une valeur plus petite dans New_Test(), car vous avez gardé la mienne et comme je suis sous Intel Pentium elle est trop élevée pour vous (AMD) c'est pour cela que vous obtenez 0 en valeurs moyennes à vide.
Les problèmes de débogueur avec l'assembleur ne sont pas nouveaux, moi qui fais pas mal d'assembleur, c'est la plaie!
Le principe du débogueur c’est :
1) récupérer les erreurs, comme la fonction OnErrorGosub(@Procedure())
2) faire un appel au débogueur entre chaque ligne PureBasic pour suivre l'état des registres, variables, etc. ou faire un arrêt... Le problème, c'est que l'état des registres n'est pas bien restitué au retour du débogueur. XLATB utilise le registre Ebx qui contient l'adresse du tableau, et avec le débogueur Ebx perd cette adresse.
PS : Vous devez mettre une valeur plus petite dans New_Test(), car vous avez gardé la mienne et comme je suis sous Intel Pentium elle est trop élevée pour vous (AMD) c'est pour cela que vous obtenez 0 en valeurs moyennes à vide.
J'en avais pas parlé, mais j'avais inclus l'affichage des pages default dans le graphique. Voici un code qui en provoque :
Code : Tout sélectionner
Global MonTest.ITest = New_Test(0)
For t=0 To #ITest
MonTest\Start(1)
AllocateMemory(500)
MonTest\Stop(1)
Next
MonTest\SetTitle(1, "AllocateMemory")
;/
For t=0 To #ITest
MonTest\Start(2)
MonTest\Stop(2)
Next
MonTest\SetTitle(2, "A vide")
MonTest\Display(2)