Pourquoi l’ordre d’exécution des subroutines donne des temps

Sujets variés concernant le développement en PureBasic
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Pourquoi l’ordre d’exécution des subroutines donne des temps

Message par PAPIPP »

Bonjour à tous.
Voici le Pb sur lequel je suis tombé.
En explorant les tutoriaux je suis tombé sur [TUTO]-Calcul des nombres premier par flaith
Comme j’ai voulu l’optimiser j’ai eu la surprise de voir des temps différents suivant l’ordre dans lequel on exécute les subroutines.
L’optimisation porte sur deux remarques :
1) il n’est pas nécessaire de tester les diviseurs sur toute l’étendu mais de le limiter à sqr(nombre_total) c'est-à-dire à la racine carré
du max de l’étendu.
2) il n’est pas nécessaire aussi de tester les nombres pairs ne testons que les nombres impairs en ajoutant à la liste 1 et 2 qui sont premiers.
Voici les trois subroutines :
1) La sub1 l ’originale.
2) La sub2 limitant les diviseurs à la racine carré de nombre_total.
3) La sub3 qui en plus de la sub2 ne teste que les nombres impairs.

QUESTION ;
La sub3 la plus optimisée prend dans certain ordre plus de temps que la sub2.
Pourquoi l’ordre d’ exécution des subroutines donne pour chacune des subroutines des temps différents ?

Code : Tout sélectionner

; Note: le débogueur doit être activé
; Affiche la liste des nombres premier allant de 1 à 'nombre_total'
ProcedureDLL.q nbcs()
!RDTSC
  ProcedureReturn
EndProcedure
nbprem1=0
nombre_total=1000
nblim=Sqr(nombre_total)
Gosub sub1
Gosub sub2
Gosub sub3
Debug "************** résultat ordre sub1 sub2 sub3"
Gosub subtot
; *****  en inversant l'exécution de  sub2 et sub3 on obtient des résutats différents
Gosub sub1
Gosub sub3
Gosub sub2
Debug "************** résultat ordre sub1 sub3 sub2"
Gosub subtot

Gosub sub3
Gosub sub2
Gosub sub1
Debug "************** résultat ordre sub3 sub2 sub1"
Gosub subtot
; ***** en ne prenant que sub2 et sub3

Gosub sub3
Gosub sub2
Debug "************** résultat ordre sub3 sub2"
Gosub subtot

Gosub sub2
Gosub sub3
Debug "************** résultat ordre sub2 sub3"
Gosub subtot

End
; ***************************************************  SUB1 *******************************************************************
sub1:
nbprem1=0
d1.q=nbcs()
E1.q=ElapsedMilliseconds()
; ***************  algo d'origine trouvé sur les tutoriaux  ****************

Debug "Liste des nombres premier allant de 1 à "+Str(nombre_total)+" algo 1"
For nbprem=1 To nombre_total
  nb_division=0
  For x=1 To nombre_total
    If nbprem%x=0                 ;Résultat du reste de la division (modulo) = 0
      nb_division+1                 ;ajoute 1 au nombre de division actuel
    EndIf
  Next
  If nb_division=2                  ;Divisible par 1 et par lui même (donc 2 fois)
    Debug Str(nbprem)     ;Alors c'est un nombre premier
    nbprem1+1
  EndIf
Next
r1.q=nbcs()-d1
Re1=ElapsedMilliseconds()-E1
Return
;**************************************************** SUB3 ********************************************************************
sub3:
; ***************  algo en limitant la recherche des diviseurs à sqr(nombre_total) en sautant de 2 en 2 ****************

Debug "Liste des nombres premier allant de 1 à "+Str(nombre_total)+" algo 3"
Debug 1
Debug 2
nbprem3=2
E3.q=ElapsedMilliseconds()
D3.Q=nbcs()
For nbprem=3 To nombre_total Step 2
  nb_division=0
  For x=1 To nblim
    If nbprem%x=0                 ;Résultat du reste de la division (modulo) = 0
      nb_division+1                 ;ajoute 1 au nombre de division actuel
    EndIf
  Next
  If nb_division=2 And nbprem<nblim   ;Divisible par 1 et par lui même (donc 2 fois)
    Debug Str(nbprem)                 ;Alors c'est un nombre premier
    nbprem3+1
  ElseIf nb_division=1                 ;Divisible par 1 et c'est tout  (donc 1 fois)
    Debug Str(nbprem)                 ;Alors c'est un nombre premier
    nbprem3+1
  EndIf
Next
r3.q=nbcs()-d3
re3.q=ElapsedMilliseconds()-E3
Return
; ******************************************************* SUB2 ***************************************************************
sub2:
;*******************************************************************************************************************************
; ***************  algo en limitant la recherche des diviseurs à sqr(nombre_total)  ****************
nbprem2=0
E2.q=ElapsedMilliseconds()
D2.Q=nbcs()
Debug "Liste des nombres premier allant de 1 à "+Str(nombre_total)+" algo 2"
For nbprem=1 To nombre_total
  nb_division=0
  For x=1 To nblim
    If nbprem%x=0                 ;Résultat du reste de la division (modulo) = 0
      nb_division+1                 ;ajoute 1 au nombre de division actuel
    EndIf
  Next
  If nb_division=2 And nbprem<nblim   ;Divisible par 1 et par lui même (donc 2 fois)
    Debug Str(nbprem)                 ;Alors c'est un nombre premier
    nbprem2+1
  ElseIf nb_division=1                  ;Divisible par 1 et c'est tout  (donc 1 fois)
    Debug Str(nbprem)                 ;Alors c'est un nombre premier
    nbprem2+1
  EndIf
Next
r2.q=nbcs()-d2
re2.q=ElapsedMilliseconds()-E2
Return
;****************************************  sub tot ***************************************************************************************
subtot:
Debug "T1="+Str(r1)
Debug "nbprem1="+Str(nbprem1)
Debug "T2="+Str(r2)
Debug "nbprem2="+Str(nbprem2)
Debug "T3="+Str(r3)
Debug "nbprem3="+Str(nbprem3)
Debug "re1="+Str(re1)
Debug "re2="+Str(re2)
Debug "re3="+Str(re3)

Debug "diff T1-T2="+Str(r1-R2)
Debug "diff T2-T3="+Str(r2-R3)
Return
@+
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.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Pourquoi l’ordre d’exécution des subroutines donne des t

Message par Backup »

peut etre simplement parceque le shreduler du systeme interviens
de façon propre au besoin du systeme ... :)

le principe du multitache préemptif
http://fr.wikipedia.org/wiki/Multit%C3% ... 3%A9emptif
Répondre