J'ai besoin de cobaye pour une optimisation.

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

J'ai besoin de cobaye pour une optimisation.

Message par Ollivier »

Je suis actuellement en train de tester deux optimisations pour les portes logiques présentes dans une condition If, à commencer par la porte ET.

Est-ce que vous pourriez tester ce code: il affiche 3 durées.
N°1 : optimisation n°1
N°2: code normal
N°3: optimisation n°2

Et sur les ordinateurs que j'ai utilisé, le N°3 fonctionne nickel (c'est le plus rapide). Pourtant le PC de Michael Vogel fait office d'exception: l'optimisation 3 ne fonctionne pas, elle est plus lente que la normale! J'aimerais savoir s'il y en a d'autres. ça me permettrait de comprendre pourquoi certaines configurations "freinent".

Merci!

Code : Tout sélectionner

DisableDebugger
timeBeginPeriod_(1)


Macro ExecutionIfTrue()
   ; Nothing
EndMacro

Macro ExecutionIfFalse()
   ; Nothing
EndMacro



Macro Test1()
            If A
               If B
                  ExecutionIfTrue()
               Else
                  ExecutionIfFalse()
               EndIf
            Else
               ExecutionIfFalse()
            EndIf
EndMacro



Macro Test2()
            If A And B
               ExecutionIfTrue()
            Else
               ExecutionIfFalse()
            EndIf
EndMacro




Macro Test3() ; (= If A And B)    /!\ /!\ /!\ /!\ /!\

   ! xor eax, eax
   
   ! lea edi, [v_A]
   ! scasd
   ! je l_isfalse2
   
   ! lea edi, [v_B]
   ! scasd
   ! je l_isfalse2

IsTrue2:

   ExecutionIfTrue()
   ! jmp l_endif2

IsFalse2:

   ExecutionIfFalse()

EndIf2:


EndMacro ;                        \!/ \!/ \!/ \!/ \!/




Macro Counter(InternalMacro)
      Cumul = 0
      For A = 0 To 1
         For B = 0 To 1
            InternalMacro
         Next
      Next
EndMacro




   Define Test1.I
   Define Test2.I
   Define Test3.I
   Define ValeurIni.I
   Define ValeurFin.I
   Define Cumul.I
   Define A.I = 0
   Define B.I = 0
   Define TotalTest.I = 10000000

   ValeurIni=timeGetTime_()
   For I = 1 To TotalTest
      Counter(Test1() )
   Next
   ValeurFin=timeGetTime_()
   Test1=ValeurFin-ValeurIni

   ValeurIni=timeGetTime_()
   For I = 1 To TotalTest
      Counter(Test2() )
   Next
   ValeurFin=timeGetTime_()
   Test2=ValeurFin-ValeurIni

   ValeurIni=timeGetTime_()
   For I = 1 To TotalTest
      Counter(Test3() )
   Next
   ValeurFin=timeGetTime_()
   Test3=ValeurFin-ValeurIni

   MessageRequester("Tests without debugger", "Test #1 (If a If b) = " + Str(Test1) + " ms" + Chr(10) + "Test #2 (If a And b) = " + Str(Test2) + " ms" + Chr(10) + "Test #3 (Asm /!\ with LEA) = " + Str(Test3) + " ms")

timeEndPeriod_(1)
Avatar de l’utilisateur
TazNormand
Messages : 1297
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Message par TazNormand »

Bon, je viens de lancer ton code 2 fois ; une avec Kaspersky 2008 activé, et l'autre non :

Kaspersky "ON" :
Test #1 : 157 ms
Test #2 : 137 ms
Test #3 : 216 ms

Kaspersky "OFF" :
Test #1 : 150 ms
Test #2 : 130 ms
Test #3 : 168 ms

ma config : C2D E8500, 2Go DDR2 PC8500, carte gfx HD4850, Windows VISTA Pro SP1.

Si tu as besoin de plus d'infos sur ma config, je te répondrai, mais demain surement, parce que là... dodo :D

EDIT : 3ème lancement sans KIS avant le dodo :
#1 118ms, #2 138 ms et #3 197 ms
Image
Image
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@TazNormand

Merci de t'être prêté à ce test avec des résultats variés. ça complète les stats. Pas fameux...

Ollivier
Anonyme

Message par Anonyme »

Alors deux test différent :

- le code du haut :
  • 1° = 193 ms
    2° = 154 ms
    3° = 204 ms

- le code du haut avec 100 ms de delay entre les tests :
  • 1° = 236 ms
    2° = 165 ms
    3° = 188 ms

sur un intel core 2 duo cadencé à 2.66 mhz avec 2go de RAM sur win xp sp2
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Voici pour ce qui me concerne les resultats:
Test #1 (If a If b) = 308 ms
Test #2 (If a And b) = 346 ms
Test #3 (Asm /!\ with LEA) = 300 ms
Conf de Test: Pentium M 1.7GHz, 512Mo, Windows XP SP2. Et PureBaisc 4.31

;)
Force et sagesse...
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Test #1 (If a If b) = 205 ms
Test #2 (If a And b) = 191 ms
Test #3 (Asm /!\ with LEA) = 272 ms

Mais bon, pour que le test soit à 100% fiable, il faut exécuter le code dans une section critique indivisible ! car Windows est un OS multitaches, et donc le processeur est divisé entre plusieurs processus.

Config :
4 Go Ram ( 800 Mhz Frq ) , Vista , 1066 Mhz dans l'FSB ( fréquence des bus ) , 2,27 Ghz CPU core 2 duo centrino 2 P8400 ( PC portable ) ..
voilà si ça peut te servir :)
Bonne journée..
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Test #1 (If a If b) = 192 ms
Test #2 (If a And b) = 154 ms
Test #3 (Asm /!\ with LEA) = 218 ms

Pas fameux, l'ASM :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Merci à vous! En effet, ce n'est pas fameux!

Si je devais me fier à ces données, je dirais que les PC les plus récents ont déjà l'optimisation au niveau matériel alors que les PC un peu moins récents ne l'ont pas.

L'optimisation #3 devient donc obsolète sur les dernières machines.

Par contre, je ne comprends pas pourquoi l'optimisation #1 reste plus lente sur certaines bécanes alors qu'il y a une économie d'instructions...

@Cpl.Bator & @Mytic

Je n'en doute pas que l'OS est multi-tâche et qu'il faut aussi prendre cela en compte mais, je fais une confiance aveugle à Rescator qui m'a passé cette méthode de test. Si vous trouvez qu'il y a mieux, je suis preneur. Je trouvais par exemple que compter les cycles c'était mieux, mais bon...
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

cxAlex a écrit :My Results:

Test #1 (If a If b) = 128 ms
Test #2 (If a And b) = 147 ms
Test #3 (Asm /!\ with ESI reg) = 148 ms
XP SP3, Intel Core 2 Quad @ 3,2 Ghz, Avira Antivirus
Tiens! Même pas... Voilà une nouvelle stat qui contredit la dernière règle... C'est donc l'instrument de mesure fiable qui manque.
Bon, ben j'ai l'algo optimisé mais je n'ai pas l'instrument assez fiable pour le vérifier. Si quelqu'un a une méthode de mesure assez puissante pour vérifier que la macro du premier code ci-dessous est plus rapide que la condition native (second code), s'il peut tester la différence de durée d'exécution, ça me ferait grand plaisir.

Code : Tout sélectionner

   Define A.I = 0
   Define B.I = 0

Macro ExecutionIfTrue()
   ; Nothing
EndMacro

Macro ExecutionIfFalse()
   ; Nothing
EndMacro



Macro Test1()
   ! xor eax, eax
   ! cmp [v_A], 0
   ! je l_faux
   ! cmp [v_B], 0
   ! je l_faux
vrai:
   ! or eax, 1
   ExecutionIfTrue()
   ! jmp l_fin
faux:
   ExecutionIfFalse()
fin:
EndMacro

Code : Tout sélectionner

; CODE NATIF

Macro ExecutionIfTrue()
   ; Nothing
EndMacro

Macro ExecutionIfFalse()
   ; Nothing
EndMacro

If A And B
   ExecutionIfTrue()
Else
   ExecutionIfFalse()
EndIf
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

C'est une connerie d'avoir une confiance aveugle... Je suis con...

Code : Tout sélectionner

DisableDebugger



Macro ExecutionIfTrue()
   ; Nothing
EndMacro

Macro ExecutionIfFalse()
   ; Nothing
EndMacro



Macro Test1()
   ! xor eax, eax
   ! cmp [v_A], 0
   ! je l_faux
   ! cmp [v_B], 0
   ! je l_faux
vrai:
   ! or eax, 1
   ExecutionIfTrue()
   ! jmp l_fin
faux:
   ExecutionIfFalse()
fin:
EndMacro


Macro Test2()
            If A And B
               ExecutionIfTrue()
            Else
               ExecutionIfFalse()
            EndIf
EndMacro




Macro Counter(InternalMacro)
      Cumul = 0
      For A = 0 To 1
         For B = 0 To 1
            !Rdtsc
            !Mov [v_ValeurIni], EAX
            InternalMacro
            !Rdtsc
            !Mov [v_ValeurFin], EAX
            Cumul + (ValeurFin - ValeurIni)
         Next
      Next
EndMacro




   Define Test1.I
   Define Test2.I
   Define Test3.I
   Define ValeurIni.I
   Define ValeurFin.I
   Define Cumul.I
   Define A.I = 0
   Define B.I = 0
   Define Sum.F
   Define Qty.F
   Define Mean.F

   InitSprite()
   InitKeyboard()
   OpenScreen(1024, 768, 32, "")
   For I = 0 To 300
      CreateSprite(I, 1, I + 1)
      CreateSprite(I + 300, 1, I + 1)
      StartDrawing(SpriteOutput(I) )
         Box(0, 0, 1, I, #Green)
      StopDrawing()
      StartDrawing(SpriteOutput(300 + I) )
         Box(0, 0, 1, I, #Red)
      StopDrawing()
   Next I
   CreateSprite(1001, 1024, 768)
   CreateSprite(1000, 1024, 1)
   StartDrawing(SpriteOutput(1000) )
      For XX = 0 To 1023 Step 32
         Line(XX, 0, 16, 0, #White)         
         Line(XX + 16, 0, 16, 0, #Black)         
      Next XX
   StopDrawing()
   CreateSprite(1002, 100, 768)
   StartDrawing(SpriteOutput(1002) )
      For I = 1 To 10
         YP = 384 - 30 * I
         Box(0, YP, 32, 1, #White)
         DrawText(30, YP - 8, "+" + Str(I * 10) + "%", #White, 1)
         YN = 384 + 30 * I
         Box(0, YN, 32, 1, #White)
         DrawText(30, YN - 8, "-" + Str(I * 10) + "%", #White, 1)
      Next I
      Box(0, 384, 32, 1, #White)
      DrawText(550, 384 - 8, "0%", #White, #Black)
   StopDrawing()
   Delay(250)
   Repeat
   Delay(16)
   DisplaySprite(1001, 0, 0)
   For x = 0 To 1023
      Test1 = 0
      Test2 = 0
      Test3 = 0
      Counter(Test1() ): Test1 - Cumul
      Counter(Test2() ): Test2 - Cumul
      Delta.F = (Test1 - Test2) * 300 / Test2
      Sum + Delta
      Qty + 1.0
      Mean = Sum / Qty
         If Delta > 0
            If Delta > 300: Delta = 300: EndIf
            DisplaySprite(Delta + 300, x, 384)
         Else
            If Delta < 0 - 300: Delta = 0 - 300: EndIf
            DisplaySprite(- Delta, x, 384 + Delta)
         EndIf
      ExamineKeyboard()
      If KeyboardReleased(#PB_Key_Space)
         Repeat
            Delay(16)
            ExamineKeyboard()
         Until KeyboardReleased(#PB_Key_Space) Or KeyboardPushed(#PB_Key_Escape)
      EndIf
      If KeyboardPushed(#PB_Key_Escape)
         Quit | 1
      EndIf
   Next
   DisplaySprite(1000, 0, 384 + Mean)
   DisplayTransparentSprite(1002, 512, 0)
   FlipBuffers()     
   Until Quit
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Par contre, je ne comprends pas pourquoi l'optimisation #1 reste plus lente sur certaines bécanes alors qu'il y a une économie d'instructions...
PB gère déjà l'économie d'instruction sur les conditions (vu avec Fred)

Donc dans if A and B, si A = 0, on s'arrête la, on passe au Else
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Ah... Et dans le tout dernier code, est-ce que tu la vois la ligne horizontale noir et blanc?

Ollivier
Répondre