It's not a bug, it's a feature

Il futuro dei linguaggi di programmazione dal MIT

I nuovi linguaggi di programmazione (tra cui Milk) porteranno a un incremento della velocità nei problemi più comuni dell’era dei Big Data.

Nei microprocessori di oggi, la gestione della memoria è basata sul principio di località: se un programma ha bisogno di alcuni dati in un particolare punto della memoria, probabilmente avrà bisogno a breve anche dei dati vicini.

Ma questo assunto viene meno nell’era dei Big Data: ogni processo è solito ad elaborare pochi dati presi arbitrariamente tra i tantissimi presenti. In genere l’accesso alla memoria RAM è di per sè la parte più dispendiosa dell’elaborazione (escluso l’accesso alle memorie fisiche), e quindi accedervi ripetutamente rallenta di molto l’elaborazione di grosse quantità di dati.

Questa settimana, alcuni ricercatori del Computer Science and Artificial Intelligence Laboratory (CSAIL) del MIT, alla conferenza internazionale sulle architetture parallele e tecniche di compilazione, hanno presentato un nuovo linguaggio di programmazione, chiamato Milk, che permette di gestire la memoria più efficacemente in programmi che hanno bisogno di accedere a dati particolari in dataset di grosse quantità.

Nei test di molti algoritmi, i programmi scritti in Milk si sono mostrati molto più veloci di quelli scritti nei linguaggi di programmazione fino ad oggi esistenti. Ma non basta: si pensa che questo linguaggio sia solo l’inizio, e che con altro lavoro si possa ottimizzare ancora di più. 

La ragione per cui una grande quantità di dati è problematica dal punto di vista della gestione della memoria non è il fatto che siano molti dati in cui cercare, ma il fatto che i dati particolari da ricercare sono pochi, e quindi rari e sparsi, fra i tanti.

Con l’arrivo dei Big Data, si crea quindi questa problematica. Non si hanno più pochi dati al quale accedere regolarmente e frequentemente, ma una vera e propria marea di dati, ai quali si accede però con la stessa frequenza e accuratezza di prima. Il problema non è quindi accedere a tutti i dati, ma accedere ai giusti dati fra i tantissimi che si hanno a disposizione.

In termini sociali, un venditore di libri che ha 1000 clienti, può essere intenzionato a inviare a tutti i 20 libri migliori del mese. Ma se lo stesso venditore accresce il numero di clienti a un milione, non è vero che sarà intenzionato a mandare una lista di 20 mila libri ad ognuno. La lista, rimarrà di 20.

Crescono quindi i dati, ma ad ogni operazione, se ne continuano ad utilizzare pochi.
Il problema, è trovarli.

Pensare logicamente

I microprocessori di oggi non sono ottimizzati per questo tipo di dati sparsi, ma al contrario per l’utilizzo di tutti i dati in sequenza. Come detto, accedere alla RAM è un processo lento, per questo esistono le memorie cache: memorie molto veloci ma con una capacità molto bassa. La questione è: quali dati caricare in cache?
Allo stato attuale delle cose, vengono appunto caricati blocchi di dati adiacenti, secondo il principio di località. 

Questo principio funziona molto bene in alcuni casi, ad esempio con l’elaborazione delle immagini. Se vogliamo applicare un filtro all’immagine, lo applicheremo man mano ad ogni blocco di immagine. Quando viene richiesto un blocco, però, parallelamente, vengono caricati i successivi blocchi in memoria cache, in modoc he finita l’elaborazione del primo, ci sia già il secondo blocco pronto in cache.

Ma questo approccio non funziona se stiamo cercando 20 libri particolari tra i 2 milioni di un rivenditore online: Se richiediamo i dati di un libro, è molto probabile che i dati dei libri adiacenti siano totalmente inutili, in quanto il prossimo libro di nostro interesse sarà a qualche migliaio di libri di distanza.

Accedere alla memoria per ogni libro, però, è inefficiente. “Immaginate di fare colazione: aprite il frigo, prendete il latte, lo versate nel cucchiaio, chiudete il frigo. Vi bevete il cucchiaio di latte, e ripetete il procedimento per ogni cucchiaio. ” dice Vladimir Kiriansky, uno studente  PhD in ingegneria elettronica e informatica, e autore del paper a riguardo.

Batch processing e linguaggi di programmazione

Milk aggiunge alcuni comandi a OpenMP, un’estensione di linguaggi come C e Fortran che rende facile lo sviluppo per processori multicores. Con Milk, un programmatore dovrà scrivere solo alcune righe di codice in più per gestire alcune operazioni che richiedono iterazione in una grande quantità di dati, e il compilatore Milk deciderà come gestire la memoria efficacemente.

In un programma Milk, quando un core deve richiedere un dato dalla memoria, non lo richiede (insieme ai dati adiacenti) ma aggiunge l’indirizzo di memoria da richiedere ad una lista. Quando le liste di ogni core sono lunghe abbastanza, vengono messe insieme e vengono raggruppati gli indirizzi di memoria vicini, e ridistribuiti ai vari cores con questi raggruppamenti. In questo modo, ogni core riceverà più dati di cui ha bisogno con un solo accesso.

Questo, è ciò che succede ad alto livello, ma nel dettaglio, le cose si fanno complicate. Nei processori moderni, ci sono più livelli di cache, ognuno più grande e lento dell’altro. Il compilatore Milk tiene conto non solo degli indirizzi di memoria, ma anche di quelli in cache in tutti i livelli. Deciderà anche quali indirizzi tenere e quali scartare dalla cache.
Ed è proprio qui che sta quella sopracitata possibilità di ulteriore miglioramento: l’algoritmo ad oggi sviluppato per gestire questi indirizzi è sicuramente più efficiente del principio di località, ma può essere ancora ottimizzato. 

“Molte applicazioni importanti al giorno d’oggi richiedono una grande quantità di dati, ma sfortunatamente, la costante crescita del gap di performance tra CPU e memoria porta a non utilizzare al massimo le prestazioni della CPU” dice Matei Zaharia, un professore alla Standfor University. “Milk aiuta a ridurre questa differenza di prestazioni ottimizzando l’accesso alla memoria in alcuni dei costrutti di programmazione più frequenti”.

Questo lavoro combina conoscenze dettagliate della progettazione del controllo di memoria, e conoscenze dettagliate dei compilatori, per implementare una soluzione che ottimizzi l’utilizzo dell’hardware di oggi.

 

Fonti:
web.mit.edu/newsoffice/
http://news.mit.edu/2016/faster-parallel-computing-big-data-0913

Published by
Redazione