Optimisation Boucle / Addition

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Ganagyre
Messages : 67
Inscription : jeu. 09/nov./2006 13:41
Localisation : PACA

Optimisation Boucle / Addition

Message 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)) 
;    
+
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Optimisation Boucle / Addition

Message 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.
Répondre