sabato 31 dicembre 2011

Il codice che mai si vede



Un programmatore solitamente ha a che fare nella sua carriera con svariati linguaggi di
programmazione. La tecnologia di oggi dà ai programmatori una serie di tools che ci
assiste lungo tutta la catena produttiva nascondendo nello stesso tempo tutti gli step ed i
prodotti intermedi della programmazione. Diciamo quindi che se non si è un
programmatore che si occupa della scrittura di driver o di codice di sistema di basso
livello, difficilmente si avrà la possibilità di vedere il codice Assembly generato dal
compilatore. Eppure oggi l’evoluzione più interessante che investe il mondo dei compilatori
si gioca proprio sulla capacità di generare codice Assembly sempre più ottimizzato
soprattutto nell’ottica di un diffondersi sempre più massivo di processori per dispositivi
mobili e che quindi dispongono di risorse più limitate rispetto ad un computer tradizionale.
Chi programma da un po’ di tempo sicuramente avrà studiato (all’università o per conto
suo) un po’ di Assembly per processori come il mitico Z80 o il Motorola 68000
(ricordiamoci che nel 2011 si sono festeggiati i primi quarant’anni del primo processore
Intel 4004) e quindi parole come “mov” o “jmp” suoneranno abbastanza famigliari. Come
dicevo prima, l’evoluzione dei “code generator” di molti compilatori è più che mai viva.
Qualche esempio pratico. Consideriamo il seguente frammento di codice (sample.c):

struct Array
{
 size_t Size;
 double *Data;
}
void MyFunc (struct Array *A)
{
 for(size_t i = 0; i < A->Size; i++)
 {
  A->Data[i] += i;
 }
}


Proviamo a vedere che tipo di Assembly genera un compilatore di ultima generazione
come LLVM. Per fare questo scriviamo da linea di comando: clang -c -O2 -S sample.c che
genera un file sample.s contenete il codice Assembly. Se diamo un’occhiata a questo file
troveremo qualcosa del genere circa la sezione di codice che descrive il ciclo for:

## BB#1:
   xorl %eax,%eax
   movsd LCPI0_0(%rip), %xmm0
LBB0_2:        ## => This Inner Loop Header
   movq 8(%rdi),  %rci   ## load A->Data
   movsd (%rcx, %rax,8), %xmm1
   addsd %xmm0,  %xmm1
   movsd %xmm1,  (%rcx, %rax,8)
   incq %rax
   movq (%rdi),  %rdx   ## load A->Size
   cmpq %rdx,  %rax
   jb  LLB0_2

In questo caso il compilatore, senza ulteriori indicazioni, si mantiene su una posizione
molto conservativa e solida ricaricando ad ogni ciclo sia il puntatore alla size, sia il
puntatore ai dati. Noi sappiamo però dalla teoria del linguaggio che due puntatori a tipi di
dato diversi non possono essere uno l’alias dell’altro, non è quindi necessario ricaricare i
due puntatori ad ogni ciclo. Diciamo questo al compilatore LLVM scrivendo:
clang -c -O2 -fstric-aliasing -S sample.c
Così facendo otteniamo un Assembly così generato (sample.s)

## BB#1:
   xorl %eax,%eax
   movsd LCPI0_0(%rip), %xmm0
   movq 8(%rdi),  %rci   ## load A->Data
   movq (%rdi),  %rdx   ## load A->Size
LBB0_2:        ## => This Inner Loop Header
   movsd (%rcx, %rax,8), %xmm1
   addsd %xmm0,  %xmm1
   movsd %xmm1,  (%rcx, %rax,8)
   incq %rax
   cmpq %rdx,  %rax
   jb  LLB0_2

Questo incrementa le performance del codice generato di quasi il 30% su codice
contenete molti cicli.
Altro esempio. LLVM dalla versione 3.0 ha una funzionalità che si chiama “Instruction
Scheduler” che consente di ottimizzare, ordinandole, le istruzioni Assembly in base ai
tempi di ciclo in modo da non tenere in sospeso delle istruzioni durante l’esecuzione di
istruzioni più pesanti. Meglio presentare un esempio per capirci meglio.
Consideriamo questa porzione di Assembly generata dal compilatore GNU gcc (versione
4.2):

r2 = add r0, r1 ## 1 ciclo
r3 = load [addr] ## 2 cicli
  // aspetta un ciclo
r4 = sub r2, r3 ## 1 ciclo

La stessa porzione di Assembly generata dal compilatore LLVM (versione 3.0) risulta
invece essere:

r3 = load [addr] ## 2 cicli
r2 = add r0, r1 ## 1 ciclo
r4 = sub r2, r3 ## 1 ciclo

qui non si ha alcuna attesa e quindi il codice eseguibile è decisamente più performante.
Concludendo è sul campo di battaglia del codice che mai nessuno vede che si sta
combattendo la guerra per scrivere programmi ed applicazioni sempre più veloci ed in
grado di cavalcare l’onda dell’evoluzione hardware. Un’altra evoluzione paradigmatica
importante è CUDA, ma di questo ne parleremo un’altra volta.

Luca Ciciriello

martedì 27 dicembre 2011

iOS & Android vendite record per Natale 2011



Tempo di crisi e tempo di record di vendite per terminali iOS e Android.
In questo Natale infatti è stato battuto clamorosamente il record di vendite: si è passati infatti dai 2.8 milioni di attivazioni di Natale 2010 ai 6.8 milioni del Natale appena trascorso.

Secono il sito Flurry anche le App hanno avuto un incremento di download arrivando a sfondare i 242 milioni di download proprio il giorno di Natale.

Infine il Vice Presidente di Google Andy Rubin ha dichiarato che Android è arrivata ad un numero di attivazioni giornaliere pari a 700 mila terminali, mentre secondo altri rumors Apple ha venduto oltre 250 milioni di pezzi nell'ultimo quadrimestre.

lunedì 26 dicembre 2011

12 giorni di Natale Apple



Apple ha iniziato da oggi a regalare ai propri clienti musica, video musicali, app e ebook.

Andando in questa pagina potete visitare su iTunes l'app da installare nel vostro device Apple e cominciare a scaricare i vostri regali.

Buon download.

martedì 20 dicembre 2011

Seagate e Western Digital riducono la garanzia sugli hard disk






Entrambi i colossi fornitori di hard disk hanno in programma un taglio della garanzia sui propri prodotti.


Le motivazioni ufficiali sono legate ad una politica di risparmio del post-vendita da reinvestire nella ricerca e sviluppo.

Secondo molti esperti però questo taglio è dovuto ad una ricerca di risparmio economico, da reinvestire per la ricostruzione dopo l'alluvione che ha flagellato la Thailandia.

giovedì 8 dicembre 2011

SHRDLU, cerca di capirmi...

Molti studiosi, sia nel passato, sia oggi, ricercano la scintilla dell’intelligenza studiando i
meccanismi più profondi del funzionamento del nostro complicatissimo cervello. Studiano
come i neuroni, gli elementi base del cervello, interagiscono tra di loro e cercano di
riprodurre artificialmente questa interazione. E’ questo l’approccio giusto per capire e
riprodurre l’intelligenza? Non lo so. A me sembra che studiare l’intelligenza in questo modo
sia un po’ come cercare di capire il senso di quello che c’è scritto in questa pagina
studiando le interazioni elettriche dei transistor del processore montato sulla macchina che
visualizza queste righe. E poi, come definiamo noi il termine “intelligenza”? Quali sono le
caratteristiche che un’entità deve possedere per poter essere definita intelligente?
Partiamo da una considerazione. Noi ci definiamo una specie intelligente. Quale è il tratto
distintivo che differenzia la nostra specie dalle altre? La risposta è semplice: il linguaggio.
Il nostro linguaggio è il più articolato e complesso di qualsiasi altra specie vivente su
questo pianeta. Terry Winograd ha seguito la strada del linguaggio naturale per lo studio
dell’intelligenza artificiale. Nel 1968, Winograd ha iniziato la sua tesi di dottorato scrivendo
un programma in LISP che sarebbe stato in grado di “capire” le intenzioni di comandi dati
in Inglese naturale. Il programma si chiamava (...e si chiama) SHRDLU. All’epoca
SHRDLU girava su un DEC PDP-6 ed occupava un’intera bobina da 6 pollici. Il nome
SHRDLU deriva da ETAOIN SHRDLU che era il nome con cui era identificata la tastiera
della Linotype Machine (un po’ il precursore della nostra QWERTY).
SHRDLU era in grado di capire frasi (contestualizzate in un mondo ad hoc chiamato “il
mondo dei blocchi”) del genere: “SHRDLU sposta il blocco rosso più piccolo rispetto a
quello che stai reggendo adesso e che si trova sotto al blocco a forma di piramide di
colore verde”. Per un essere umano è banale disambiguare una frase del genere, ma per
un programma software diventa un incubo analizzare semanticamente questa frase. La
tesi di dottorato di Winograd si concluse nel 1970 e nel 1972 SHRDLU divenne il più
famoso programma software (e forse il primo) catalogabile sotto la categoria di
Computational Linguistic, branca della Computer Science affascinante e tuttora in fase di
enorme sviluppo. SHRDLU è ancora attivo e liberamente scaricabile per diverse
piattaforme all’indirizzo: http://hci.stanford.edu/winograd/shrdlu/.
Oggi molte ricerche sono orientate all’analisi del linguaggio naturale da parte di software
sempre più sofisticati. Si pensi all’ormai famoso Apple Siri, un programma di analisi
linguistica
che è in grado di tenere una conversazione credibile su qualsiasi argomento ed
eseguire comandi. Siri è disponibile in versione beta sul dispositivo mobile (iPhone 4S)
della Apple. Informazioni su Siri sono disponibili a questo indirizzo: http://www.apple.com/
iphone/features/siri.html
Sempre su iPhone è disponibile una mia applicazione (un po’ di pubblicità non va mai
male) in grado di eseguire l’analisi logica di una frase qualsiasi in inglese, classificando le
parole contenute nella frase in verbi, nomi, aggettivi, ecc. “Grammatica”, la mia
applicazione, è in grado anche di identificare all’interno della frase nomi propri, date,
indirizzi e numeri di telefono. Informazioni su Grammatica possono essere trovate al sito
Apple: http://itunes.apple.com/app/grammatica/id482570158?ign-mpt=uo%3D6&mt=8.
Molti altri studi sono in corso in Computational Linguistic. Per chi fosse interessato
all’argomento, un sito molto bello e pieno di articoli liberamente accessibili è quello del
MIT: http://www.mitpressjournals.org/loi/coli.
Per concludere ritengo la Computational Linguistic un approccio più sensato da perseguire
nella ricerca sull’intelligenza artificiale rispetto all’approccio botton-up della maggior parte
delle ricerche oggi attive in questo campo.
Luca Ciciriello.