Programmazione parallela: pensieri sparsi

13. aprile 2010

Venerdì scorso ho partecipato all'evento DotDotNet (grazie ancora a chi organizza gli eventi e le cene!) sui temi F# e Continous Integration .

Durante la discussione su F# è stata evidenziata la sua innata abilità nel semplificare notevolmente la parallelizzazione dei task (aspetto secondario del tema in quanto F# è principalmente un linguaggio dinamico e funzionale).

A parte lo scontato utilizzo di F# in ambito matematico/scientifico/fisico il tema della parallelizzazione mi ha fatto pensare ai concetti di performance (ovviamente) ma soprattutto ad un qualcosa che mi piace chiamare "Codice Predittivo", similmente alla prediction branch delle CPU.

Il trend di mercato per quanto riguarda le CPU è oggi meno indirizzato sulla velocità pura di clock ma piuttosto nell'integrazione di un numero sempre maggiore di core sullo stesso chip.

La sfida a livello software per i prossimi anni è quindi quella dello sfruttamento multithread di tutti questi core.

Uno scenario che mi incuriosisce è questo: ho un'applicazione che effettua alcune operazioni (A(x), B(x), C(x) ecc) e ogni operazione può essere applicata indistintamente al risultato di qualsiasi altra.

Ipotizziamo di eseguire A(x) e magari di fermarci per osservare il risultato ottenuto e decidere quali altre operazioni eseguire.

In questo momento potremmo pensare di sfruttare tutti i core inattivi della macchina per eseguire ad esempio B(A(x)) oppure C(A(x)) o ovviamente qualsiasi altra operazione in background e multithread.

A questo punto l 'utente decide che vuole eseguire l'operazione B(A(x)) e voilà, il risultato è già disponibile.

Una user experience non male direi.

A questo punto scarto i risultati non utilizzati e proseguo allo stesso modo. Ho solo sprecato un po' di cicli di qualche core che non faceva niente...

Il più immediato esempio concreto è nel settore del fotoritocco. Applico un filtro ed intanto l'applicazione ne applica altri che potrei usare in futuro (o addirittura potrebbe applicare i filtri che utilizzo con maggiore frequenza).

Microsoft stà lavorando alacremente nel settore della parallelizzazione per fornire agli sviluppatori un set di librerie per rendere il più semplice e trasparente l'esecuzione di codice su più core. Il risultato si chiama PLINQ che è l'implementazione parallela del pattern LINQ.

Allo stesso modo di LINQ, PLINQ è un insieme di extension method che operano su un IEnumerable<T> in memoria e sfruttano la deferred execution. La principale differenza stà nel fatto che PLINQ suddivide la sorgente dati in segmenti e cerca di eseguire l'operazione in parallelo su tutti i processori/core presenti nel sistema.

Il tutto partendo da un livello veramente base: basta invocare l'extension method AsParallel() per richiedere l'esecuzione in parallelo fino ad un massimo di 64 processori.

Reference:

PLINQ: http://msdn.microsoft.com/en-us/library/dd460688(VS.100).aspx

http://en.wikipedia.org/wiki/Plinq#PLINQ

F# : http://msdn.microsoft.com/en-us/fsharp/default.aspx

http://en.wikipedia.org/wiki/F_Sharp_(programming_language)

.net Framework, C# e VB.net

Unit Test e AutoCad: si può fare!

10. aprile 2010

Lo sviluppo di nuove feature e/o applicazioni integrate con AutoCad è diventato incredibilmente più produttivo da quando sono state introdotte le librerie ObjectArx in formato .Net.

L'unico (grosso) limite che ho riscontrato fino a poco tempo fa è stata l'impossibilità di utilizzare framework di test e di mocking.

Questo perchè i plugin sviluppati devono necessariamente essere caricati lanciando AutoCad stesso e funzionano nel thread principale della UI (e ovviamente non è possibile mokkare Autocad...).

Fino ad oggi quindi i test li avevo scritti completamente a mano, creando man man tutti gli oggetti necessari.

Recentemente ho trovato questa piattaforma di automazione: Gallio

Oltre a fornire il supporto per tutti i principali framework di test (NUnit, MSTest, xUnit ecc) e ai principali strumenti di mocking e di continous integration, Gallio è in grado di automatizzare l'esecuzione di test all'interno di Autocad.

Il funzionamento alla base è concettualmente semplice: Gallio carica uno shimW all'interno di AutoCad che si occupa di intercettare le chiamate alle API e di eseguire i comandi.

Il testing su Autocad non è integrato nell'IDE di Visual Studio ma si tratta di una lacuna veramente minima in quanto è comunque disponibile un'interfaccia GUI simile a quella di nUnit oltre ovviamente al runner a riga di comando (il che chiude il cerchio in quanto è possibile far eseguire i test su un server di Continuous Integration).

I dubbi sono per ora due.

Il primo riguarda uno scarsa partecipazione e dinamicità nello sviluppo di Gallio; l'ultima release risale a novembre 2009.

In secondo luogo viene un po' meno uno dei principi base dei test unitari: la rapidità di esecuzione.
Per eseguire i test infatti Gallio deve caricare 2 volte AutoCad: una prima volta ad ogni rebuild della libreria dei test ed una seconda volta per eseguirli richiedendo quindi alcuni secondi di attesa.

.net Framework, AutoCAD e ObjectARX ,