Vai al contenuto
PLC Forum


Tempi elaborazione


batta

Messaggi consigliati

Ho fatto una funzione per riordinare gli elementi di un array (100 elementi).
Ho adottato il metodo classico col doppio ciclo FOR, quindi, per riordinare questi 100 elementi, servono circa 5000 cicli del FOR interno (4950, per essere precisi).

Avevo provato anche col metodo "bubblesort", ma si rivela meno efficiente.
Trattandosi di un numero non trascurabile di cicli, ho pensato di rilevare il tempo necessario all'elaborazione (con istruzione RUNTIME),

e volevo mettervi al corrente di quanto è emerso da queste prove:

1) a differenza del 300, nel 1500 lavorare sulle variabili TEMP o sulle variabili STAT non comporta nessuna differenza di tempo

2) la differenza tra lavorare con il blocco ottimizzato o non ottimizzato, è di circa 5 volte

 

Magari non interessa a nessuno.

Link al commento
Condividi su altri siti


8 minuti fa, batta scrisse:

Magari non interessa a nessuno.

 

Se c'è qualcuno che lavora seriamente dovrebbe essere interessato a queste tue verifiche.

 

Link al commento
Condividi su altri siti

Rettifica...

 

Dunque, se sposto l'array da TEMP a STAT (e viceversa), il tempo di elaborazione non cambia.

Invece se sposto le variabili usate come indici dei cicli FOR (le classiche "i" e "j") da TEMP in STAT, il tempo aumenta di circa 3 volte.

Se, con gli indici dei cicli FOR nelle STAT tolgo l'ottimizzazione, il tempo di elaborazione non diventa più di 5 volte, ma circa 2 volte.

 

Boh, non capisco come vengano gestiti gli accessi alle variabili.

Non so più quando vale la pena appoggiarsi sulle TEMP, e quando invece non serve a nulla.

Link al commento
Condividi su altri siti

Questo esperimento ti serviva per fare un esperimento o ti serviva per un lavoro?

Per quanto riguarda il riordino l'array era stato caricato in modo da fare 4950 cicli oppure li fa sempre anche se l'array dovesse essere in parte già otimizzato?

Inoltre hai percaso provato a riordinare l'array con un loop fatto in AWL?

Per vedere la differenza

Link al commento
Condividi su altri siti

L'ordinamento dell'array mi serve per un lavoro e, con l'occasione, ho cercato di capire quanto "pesava" in termini di tempo di elaborazione.

Ho provato i metodi "selection sort" e "bubble sort".
Selection sort effettua sempre N*(N-1)/2 confronti. Nel caso dei 100 elementi del mio array, 100*99/2 = 4950 (verificati anche con un contatore nel ciclo FOR interno).

Bubble sort effettua lo stesso numero di confronti ma, nel caso di array già ordinato, può essere interrotto prima.
Nelle mie prove però il metodo bubble sort si è rilevato meno efficace. Non ho approfondito il perché. Immagino sia perché effettua potenzialmente meno confronti ma più scambi, ma potrei anche dire una cavolata.

 

In ogni caso, cambiare il codice da un metodo all'altro non è certo un problema.
 

Comunque, la questione non è "come riordinare un array", ma capire le differenze di tempo di elaborazione tra blocchi ottimizzati e non ottimizzati, e accesso a variabili STAT, IN, OUT, IN/OUT, TEMP.

 

Nelle mie prove ho sempre dato in pasto lo stesso array da riordinare, in modo da essere sicuro di effettuare sempre gli stessi confronti e gli stessi scambi.
I risultati sono quelli descritti nel mio precedente post.

 

Che dire, in una specie di corso Siemens fatto ancora alla nascita dei 1200/1500 il tecnico Siemens aveva affermato che la differenza tra blocco non ottimizzato e ottimizzato è 6/1.
Direi che quello che ho rilevato io si avvicina molto.
Quello che invece non riesco a spiegarmi, è che non cambia nulla se sposto gli elementi dell'array da TEMP a STAT, invece cambia moltissimo se sposto da TEMP a STAT gli indici.

 

La funzione è stata sviluppata in SCL. Non ho fatto la prova in AWL.

Link al commento
Condividi su altri siti

E' molto strano che facendo il cambio da Temp a Stat non rilevi differenze mentre facendo il contrario si.

Le temp hanno un accesso alle locali Mentre le stat sono sul DB di istanza , e quindi quando accedi alle stat IL PLC dovrebbe aprire il DI solo la prima volta, e quindi essere equivalente all' accesso delle locali.

Per quanto riguarda l'ottimizzazione pensavo fosse solo un discorso di spazio nel PLC , anche se so che le variabili Bool occupano un Byte

Link al commento
Condividi su altri siti

Quote

E' molto strano che facendo il cambio da Temp a Stat non rilevi differenze mentre facendo il contrario si.

No, forse non mi sono spiegato bene.
Nelle prove effettuate ho constatato che spostando da STAT a TEMP, o viceversa, le variabili dell'array, non cambiava nulla.
Cambiava molto invece spostando da STAT a TEMP, o viceversa, le variabili usate come indici.

 

Ora non ho più a disposizione la stessa CPU, e sto facendo delle prove con una vecchissima (e lentissima) 1212, con FW 2.2.

Ho migliorato il codice. Ora il numero di confronti è sempre pari a N * (N-1) / 2, ma il numero di scambi è, nella peggiore delle ipotesi, pari a N-1.
Nel precedente codice il numero di scambi era molto più alto.
 

Ecco il codice:

    // Azzero conteggio confronti e conteggio scambi (solo per debug)
    #CompCnt := 0;
    #SwapCnt := 0;
    // Effettuo ciclo FOR dal primo al penultimo elemento dell'array
    FOR #i := 1 TO #n - 1 DO
        // Devo ricercare elemento con valore da riordinare più basso.
        // Inizializzo "elemento minimo" con valore indice "i"
        #i_min := #i;
        
        // Effettuo ciclo FOR da elemento immediatamente successivo a quello da confrontare
        // fino a ultimo elemento dell'array
        FOR #j := #i + 1 TO #n DO
            #CompCnt := #CompCnt + 1;     // Incremento conteggio confronti (solo per debug)
            // Se trovo elemento con valore più basso, correggo indice "elemento minimo".
            // Alla fine di questo ciclo FOR, "i_min" contiene indice dell'elemento con valore più basso
            IF #SortArray[#j].UDIntVar < #SortArray[#i_min].UDIntVar THEN
                #i_min := #j;
            END_IF;
        END_FOR;
        // Se "i_min" è divesro da "i", significa che è stato trovato un elemento con valore
        // più basso rispetto all'elemento sotto controllo.
        // In questo caso, effettuo lo scambio tra i due elementi
        IF #i_min <> #i THEN
            #SwapCnt := #SwapCnt + 1;   // Incremento conteggio scambi (solo per debug)
            #SwapStruct := #SortArray[#i_min];      
            #SortArray[#i_min] := #SortArray[#i];   
            #SortArray[#i] := #SwapStruct;          
        END_IF;
    END_FOR;

 

I risultati ottenuti con questo codice, la CPU 1212, e un array di 50 elementi (ogni elemento è una STRUCT di 1 UDInt, 1 REAL, 1 INT, 1 BOOL), sono i seguenti:
1) Blocco ottimizzato, variabili array e variabili indici tutte in TEMP: tempo scansione 90..105 ms

2) Blocco ottimizzato, variabili array in STAT e variabili indici in TEMP: tempo scansione 108..120 ms

3) Blocco ottimizzato, variabili array e variabili indici tutte in STAT: tempo scansione 110.125 ms
4) Blocco NON ottimizzato, variabili array in STAT e indici in TEMP: tempo scansione 108..120 ms (esattamente come al punto 2).

 

Ne deduco che non tutte le CPU si comportano allo stesso modo. Alla prima occasione, farò ulteriori test su una CPU più recente di quella usata per queste ultime prove.

Link al commento
Condividi su altri siti

Penso che 1500 e 1200 siano differenti di parecchio, Non credo che sia la stessa differenza che c'è tra 300-400 che a parte i 4 accumulatori del 400 e le velocità di elaborazione sono uguali.

Comunque analizzerò il problema è interessante 

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...