Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1909, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Cicli Parallel.For con Visual Basic

In un precedente post abbiamo introdotto Parallel LINQ e abbiamo visto come questo faccia parte di una tecnologia più ampia, la Parallel Task Library, che farà parte di .NET Framework 4.0 e che offre il supporto in Visual Studio 2010 al parallel computing. Nel rimandarvi al precedente post per i link ai download necessari alle estensioni per Visual Studio 2008, in questo post facciamo la conoscenza sommaria di una nuova classe chiamata Parallel e che fa parte del namespace System.Threading. La classe Parallel offre una serie di metodi Shared per eseguire alcune operazioni a livello di multi-threading (anche se nel parallel computing questa non è la terminologia esatta, ma serve per rendere l’idea) tra cui metodi per l’esecuzione di cicli, come For e ForEach.

 

Lo scopo di questo post è introdurre i cicli For secondo lo stile Parallel, mentre ci occuperemo in futuro dei ForEach. I cicli For paralleli si scrivono in modo sostanzialmente analogo a quelli classici, mentre le differenze sono a livello di esecuzione. Capiremo meglio con un po’ di codice, che poi commenteremo (a tal proposito riprendo codice dimostrativo presente nel Visual Studio 2010 Beta 1 Training Kit).

 

Supponiamo di avere il seguente metodo, che restituisce l’identificativo del thread corrente:

 

    Function GetThreadId() As String

        Return " Thread ID = " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString

    End Function

 

Supponiamo, poi, di avere un metodo che simula un’elaborazione intensiva:

 

    'Simula un lavoro intensivo

    Sub SimulateProcessing()

        Thread.SpinWait(80000000)

    End Sub

 

Così come per Parallel LINQ, anche i cicli Parallel.For portano beneficio qualora si lavori con elaborazioni decisamente intensive, per questo facciamo tale simulazione. Una semplice iterazione, ad esempio, potrebbe non essere idonea per un ciclo parallelo.

 

Ora, consideriamo il seguente, classico ciclo For:

 

    Private Sub SomeMethod1()

        For i = 0 To 16

            Console.WriteLine(i.ToString + GetThreadId())

            SimulateProcessing()

        Next

    End Sub

 

Si tratta di un banale ciclo che esegue un conteggio progressivo da 0 a 16, visualizzando sullo schermo il valore del contatore seguito dall’identificativo del thread corrente. All’interno del ciclo viene poi richiamato il metodo che simula il lavoro intensivo. Ipotizzando di invocare tale ciclo nel metodo Main di un’applicazione Console, avviando l’applicazione stessa potremo notare innanzitutto l’utilizzo delle risorse di sistema:

La figura mostra come le risorse hardware della nostra macchina dual-core siano sfruttate in modo limitato. Alla fine del lavoro, il risultato che otterremo è simile al seguente:

Circa 27 secondi per eseguire il lavoro intensivo, che, come si può osservare, viene concentrato su un unico thread. Passiamo ora a riscrivere il ciclo secondo lo stile parallelo. Il metodo assumerà la seguente forma:

 

    Private Sub SomeMethod1()

        Parallel.For(0, 16, Sub(i)

                                Console.WriteLine(i.ToString + GetThreadId())

                                SimulateProcessing()

                            End Sub)

    End Sub

 

Si utilizza il metodo condiviso For della classe Parallel, il cui primo argomento è costituito dal valore iniziale del ciclo, il secondo da quello finale e il terzo da un delegate che esegue il lavoro effettivo. Teoricamente avremmo potuto richiamare un delegate dichiarato altrove nel codice (es. AddressOf NomeDelegateCheFaQualcosa), ma volevo illustrarvi l’utilizzo di un’altra novità di Visual Basic 2010, ossia le statement lambda. Un metodo anonimo, quindi, che rappresenta un delegate generato al volo e che non restituisce valori, che incapsula al suo interno le stesse operazioni fatte dal ciclo For classico.

 

Se ora eseguiamo nuovamente l’applicazione, le risorse della nostra architettura dual-core vengono sfruttate appieno:

E il risultato che otterremo sarà simile al seguente:

A livello di performance, il tempo impiegato è di circa 14 secondi. Quindi, circa 13 secondi in meno rispetto al ciclo For classico, sempre tenendo conto del tipo di simulazione che abbiamo fatto. Un’altra cosa molto importante da notare sono i thread utilizzati. L’utilizzo della classe Parallel, infatti, ha fatto sì che il runtime della Parallel Task Library abbia autonomamente aperto e gestito diversi thread su cui scalare l’esecuzione dell’elaborazione, senza che noi ci siamo dovuti preoccupare di farlo manualmente. E’ infatti sostanzialmente questo lo scopo di tale framework, quello di scalare su thread diversi (anche se gestiti in modo profondamente diverso rispetto al multi-threading .NET classico, come approfondiremo in seguito). Ed è questo sostanzialmente il motivo per il quale sto trattando l’argomento in un modo che va al contrario rispetto agli standard, perché andando a ritroso riusciamo a risalire al vero scopo e al funzionamento della libreria.

 

Giova ribadire che le operazioni parallele offrono benefici allorquando si ha a che fare con elaborazioni complesse e lunghe, non tanto su cicli di breve durata e di scarsa entità.

 

Alessandro

Print | posted on martedì 7 luglio 2009 02:09 | Filed Under [ Visual Basic Visual Studio 2010 Parallel Programming ]

Powered by:
Powered By Subtext Powered By ASP.NET