Condividi tramite

Basso utilizzo CPU macro VBA (Excel)

Anonimo
2022-03-19T01:24:25+00:00

Salve a tutti,

ho scritto una macro VBA che essenzialmente, dopo aver copiato in array le variabili di partenza, cicla su tutti i possibili valori che possono assumere dei parametri di una funzione al fine di trovare il miglior fitting di una serie di dati.

Funziona, ma l'esecuzione è davvero lunga. Mi sono accorto che l'utilizzo della CPU rimane costante intorno al 25%; c'è modo di sfruttare a pieno la CPU?

Grazie!

Microsoft 365 e Office | Excel | Per l'istruzione | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento

5 risposte

Ordina per: Più utili
  1. Anonimo
    2022-03-20T11:30:21+00:00

    Ciao MB22_MS,

    Allego un file di esempio, ho scritto dei commenti nel modulo della macro https://1drv.ms/x/s!AsxSPMFdun_V91aIfWmT7znv_FzV?e=FEt0lI Altre differenze col file "vero" è che in quello il codice viene lanciato da una userform, ma le prestazioni tra i due sono le stesse

    Dalle annotazioni al tuo codice vedo che hai già un codice molto più efficiente ma che, per ragioni che non mi sono chiare, desideri adottare l'approccio della forza bruta.

    Dato questo desiderio, mi rammarico che si possa fare ben poco in termini di revisione del codice per ridurre i tempi di esecuzione prolungati.

    In risposta alla tua domanda sull'aumento delle risorse della CPU allocate in Excel, ti rimando al seguente articolo in inglese Using More CPU Power when Calculating

    Infine, per consentire l'interruzione dei cicli estesi del tuo codice, prova a modificare il tuo codice come segue:

    '========>>

    Option Explicit

    '-------->>

    Sub prova()

    Dim i, n As Integer 
    
    Dim X, Y, PREVISIONE, m, m0, RSS, RSS0  
    
    ' 
    
    'ESEMPIO DI QUA: funzione y=mx  --->cerco a tentativi il miglior m, variandolo tra un m min e un m max a step impostato 
    
    'valuto il fit mediante RSS 
    
    'i parametri migliori rimangono in m0 e RSS0 
    
    ' 
    
    'nel foglio "vero" valuto una somma di curve con 3\*n°curve parametri 
    
    'quindi ci saranno una serie di cicli uno dentro l'altro, uno per ogni parametro (qua solo uno che fa passare tutti i valori di m) 
    
    'ho già pronti anche dei codici per la regressione non lineare, 
    
    'che con poche iterazioni porta allo stesso risultato (+-), ma ho necessità di usare anche questo "provale tutte" 
    
    ' 
    
    **On Error GoTo errHandler** 
    
    **Application.EnableCancelKey = xlErrorHandler** 
    
    **Call MsgBox(Prompt:="Questa procedura potrebbe richiedere molto tempo: premi ESC per annullarla")** 
    
     'copio i valori i y e x in array 
    
    X = [a1:a7] 
    
    Y = [b1:b7] 
    
    n = UBound(X) - LBound(X) + 1 
    
    ReDim PREVISIONE(1 To n) 
    
    'valutazione col valore iniziale di m 
    
    For i = 1 To n 
    
        PREVISIONE(i) = m \* X(i, 1) 'valuto la funzione col parametro attuale 
    
        RSS0 = RSS + (Y(i, 1) - PREVISIONE(i)) ^ 2 'calcolo la somma quadratica dei residui 
    
    Next i 
    
    'provo tutte le possibilità per m 
    
    For m = 0.0001 To 100000 Step 0.0001  'ho esagerato per avere tanti calcoli: utilizzo CPU rimane costante al 25% **(a proposito, come si può arrestare una macro in esecuzione? Esc o ctrl pausa non funzionano, devo chiudere forzatamente Excel)** 
    
        RSS = 0                             'per provare senza avere una cosa lunga può per es essere For m = 0.5 To 1.5 Step 0.1 
    
        For i = 1 To n 
    
            PREVISIONE(i) = m \* X(i, 1) 'valuto la funzione col parametro attuale 
    
            RSS = RSS + (Y(i, 1) - PREVISIONE(i)) ^ 2 'calcolo la somma quadratica dei residui 
    
        Next i 
    
        If RSS < RSS0 Then 'se il fitting è migliorato "salvo" gli attuali parametri 
    
            RSS0 = RSS 
    
            m0 = m 
    
        End If 
    
    Next m 
    
    MsgBox m0 
    

    errHandler:

    **If Err.Number = 18 Then** 
    
        **MsgBox "Hai cancellato la procedura!"** 
    
        **Exit Sub** 
    
    **End If** 
    

    End Sub

    '<<========

    ===

    Regards,

    Norman

    Immagine

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2022-03-20T00:10:07+00:00

    Sì l'ordine di grandezza era pensato proprio per dare il tempo di aprire il task manager e verificare l'utilizzo della CPU, che nel mio caso è molto basso

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Gianfranco55 25,190 Punti di reputazione Moderatore volontario
    2022-03-19T18:22:15+00:00

    ciao

    mi vengono i brividi a pensare al numero

    di calcoli che fa

    For m = 0.0001 To 100000 Step 0.0001 =1000000000

    For m = 0.0001 To 10 Step 0.0001 =100000 calcoli

    immediato

    For m = 0.0001 To 100 Step 0.0001 =1000000 calcoli

    due secondi

    For m = 0.0001 To 1000 Step 0.0001 =10000000

    mi blocca il programma

    La risposta è stata utile?

    0 commenti Nessun commento
  4. Anonimo
    2022-03-19T18:00:50+00:00

    Allego un file di esempio, ho scritto dei commenti nel modulo della macro https://1drv.ms/x/s!AsxSPMFdun_V91aIfWmT7znv_FzV?e=FEt0lI Altre differenze col file "vero" è che in quello il codice viene lanciato da una userform, ma le prestazioni tra i due sono le stesse

    Grazie!

    La risposta è stata utile?

    0 commenti Nessun commento
  5. Anonimo
    2022-03-19T10:32:23+00:00

    Ciao MB22_MS,

    ho scritto una macro VBA che essenzialmente, dopo aver copiato in array le variabili di partenza, cicla su tutti i possibili valori che possono assumere dei parametri di una funzione al fine di trovare il miglior fitting di una serie di dati.

    Funziona, ma l'esecuzione è davvero lunga. Mi sono accorto che l'utilizzo della CPU rimane costante intorno al 25%; c'è modo di sfruttare a pieno la CPU?

    Per considerare la possibilità di ridurre i tempi di esecuzione della tua macro penso che sarebbe necessario che tu pubblichi il tuo codice. Ancora meglio, per consentire un adeguato test di un eventuale codice rivisto, ti chiederei gentilmente di caricare un file di esempio, privo di dati sensibili.

    Per caricare il file su Microsoft OneDrive, vedi:

       Condividere file e cartelle di OneDrive

    Per caricare il file su DropBox, vedi:

    Come faccio a condividere file e cartelle in Dropbox?

    ===

    Regards,

    Norman

    Immagine

    La risposta è stata utile?

    0 commenti Nessun commento