Page 1 sur 1

Optimisation Boucle / Addition

Publié : sam. 20/nov./2010 23:21
par Ganagyre
Bonjour à tous.

L'exemple de code suivant, effectue la recherche de la ou les séquences
de 8, le plus sortie sur l'ensemble d'un Tableau.
Cela se rapproche un peu de "l'addition de matrices".
La on additionne par "colonnes".

Le nombre de séquences à parcourir s'éleve à 536 878 650 .
50 Colonnes à combiner en 8 Groupes.
Séquences de 8 s'étalant de colonnes 1-2-3-4-5-6-8 à 43-44-45-46-47-48-49-50.
On peu jouer sur la Variable Colonnes pour réduire ce nombre.

Pour ne pas avoir les données trop fractionnées, on utilise un
Tableau Unidimensionnel = Dim TBLuni((Colonnes+1)*Lignes).

Et quelques "Tableaux Temporaire" pour échelonner les calculs.

Le Code fonctionne dans cette approche de base .

Mais reste t'il possible d'améliorer/optimiser quelque peu la vitesse de traitement :?:
(En plus de se passer du mode Débug).

Merci de toute subtilité. :wink:

Code : Tout sélectionner

temp = ElapsedMilliseconds()
;____
DisableDebugger
;____
Colonnes.l = 50 : Lignes.l = 100
total.l = 0     : compte.l = 0
demande.l = 8   : maximum.l = 6
resultat.l      : add.l
;______
; Tableau unidimensionnel  // 
Dim TBLuni((Colonnes+1)*Lignes)
;______
; Tableaux Temporaires
Dim TBLTMP1.l(Lignes) : Dim TBLTMP2.l(Lignes) : Dim TBLTMP3.l(Lignes)
Dim TBLTMP4.l(Lignes) : Dim TBLTMP5.l(Lignes) : Dim TBLTMP6.l(Lignes)
Dim TBLTMP7.l(Lignes)
;
;_____ Remplir aleatoirement TBLuni valeurs = 0/1
For i = 1 To ArraySize(TBLuni())    
  TBLuni(i) = Random(1) ; 0/1         
Next
;_____
;_____Recherche Groupe le plus Present
;
For boucle1 = 1 To Colonnes-7
;  
For boucle2 = boucle1+1 To Colonnes-6
;        
  For add = 1 To Lignes
    TBLTMP2(add) = TBLuni((boucle1*Lignes)+add) + TBLuni((boucle2*Lignes)+add)
  Next add  
;    
For boucle3 = boucle2+1 To Colonnes-5
;        
  For add = 1 To Lignes
    TBLTMP3(add) = TBLuni((boucle3*Lignes)+add) + TBLTMP2(add)
  Next add  
;
For boucle4 = boucle3+1 To Colonnes-4
;        
  For add = 1 To Lignes
    TBLTMP4(add) = TBLuni((boucle4*Lignes)+add) + TBLTMP3(add)
  Next add  
;    
For boucle5 = boucle4+1 To Colonnes-3
;        
  For add = 1 To Lignes
    TBLTMP5(add) = TBLuni((boucle5*Lignes)+add) + TBLTMP4(add)
  Next add  
; 
For boucle6 = boucle5+1 To Colonnes-2
;        
  For add = 1 To Lignes
    TBLTMP6(add) = TBLuni((boucle6*Lignes)+add) + TBLTMP5(add)
  Next add  
;         
For boucle7 = boucle6+1 To Colonnes-1
;        
  For add = 1 To Lignes
    TBLTMP7(add) = TBLuni((boucle7*Lignes)+add) + TBLTMP6(add)
  Next add  
;            
For boucle8 = boucle7+1 To Colonnes
  ;    
  For add = 1 To Lignes ;_ _ _ 
     ;
     total =  TBLTMP7(add) + TBLuni((boucle8*Lignes)+add) 
     ;
     If total = 8 ; ou variable = demande 
        resultat+1
     EndIf 
      ;
  Next add ;_ _ _
  ;  
   If resultat >= maximum ; _=_=_    
     compte+1
  ;   
     EnableDebugger    
;  
      Debug"=============================="    
      Debug "Groupe N° "+Str(compte)+" ___ "+Str(boucle1)+" = "+Str(boucle2)+" = "+Str(boucle3)+" = "+Str(boucle4)+" = "+Str(boucle5)+" = "+Str(boucle6)+" = "+Str(boucle7)+" = "+Str(boucle8)+" [ Sortie ]   =  " +Str(resultat);maximum)
;
     DisableDebugger 
;
        maximum = resultat

   EndIf ; _=_=_         
    resultat = 0
;  
Next boucle8
Next boucle7
Next boucle6
Next boucle5
Next boucle4
Next boucle3
Next boucle2
Next boucle1
;
EnableDebugger  
;
temp = ElapsedMilliseconds() - temp
MessageRequester("", Str(temp)) 
;    
+

Re: Optimisation Boucle / Addition

Publié : sam. 20/nov./2010 23:40
par djes
Je ne suis pas sûr d'avoir compris, mais si tu n'as que des 0 et des 1, tu pourrais facilement activer le bit correspondant au numéro de la colonne, et lire le résultat octet par octet (dans le cas de 8 colonnes).

D'autre part, le fait que tu utilises un tableau unidimensionnel t'oblige à faire les multiplications pour sauter à la bonne ligne toi-même. Vu le nombre, tu devrais laisser PB faire en utilisant un vrai tableau multi-dimensionnel.

Ensuite, tu pourrais parcourir ton tableau une première fois à la recherche de 0 et faire dans ce cas une élimination directe du groupe correspondant (en sautant au suivant). Tu aurais ainsi directement les résultats sans avoir besoin d'addition (je me trompe peut-être).

Enfin, il y a dans nos processeurs des instructions (MMX, SIMD...) qui permettent de lire des paquets de données et d'effectuer d'un seul coup des opérations d'addition et de comparaison. Le gain de vitesse est TRES appréciable pour ce genre de traitement.