venerdì 12 maggio 2017

VON NEUMANN E BACH: ARCHITETTURA DEL COMPUTER ED ARTE DELLA FUGA

L'ungherese (poi naturalizzato statunitense) John von Neumann (1903-1957) è stato uno dei matematici più proficui del XX secolo, fornendo decisivi contributi in svariati campi della matematica, ma anche in fisica, in economia e in informatica.
Si dice infatti di lui che fu probabilmente l'ultimo dei matematici ad avere una visione completa di tutta la matematica.
Per farsi un'idea delle capacità mostruose della mente di von Neumann, basta leggere l'aneddoto di cui ho parlato qui.
Ma che c'entra von Neumann con Johann Sebastian Bach (1685-1750), il grandissimo compositore tedesco, noto anche ai non patiti di musica classica grazie alla celebre Aria sulla quarta corda, divenuta sigla del programma Superquark?



Il nonno di von Neumann era un grande appassionato di musica e ai tempi era una delle poche persone a possedere un grammofono.
Nelle famiglie borghesi dell'epoca si era soliti formare, nei limiti delle possibilità, piccole orchestre da camera familiari.
Il piccolo János (nome di von Neumann all'anagrafe) imparò a suonare il violino e, anche se alla fine abbandonò l'intento di una carriera da musicista per sviluppare le sue notevoli doti da matematico, non perse mai la sua passione per la musica.
Una delle opere musicali che suscitò maggiormente l'interesse di von Neumann fu appunto l'Arte della fuga, un insieme di 14 fughe e 4 canoni che Bach compose al fine di esemplificare le tecniche del contrappunto.
Secondo la testimonianza del fratello Nicholas, l'Arte della fuga di Bach fu la fonte di ispirazione che, anni dopo, fece pensare von Neumann alla possibilità che un computer non avesse un programma previo assegnato, spingendolo così verso la realizzazione dell'archittetura dei computer che porta il suo nome.
Ci proponiamo dunque di spiegare in modo semplice la storia e le basi dell'architettura di von Neumann e poi l'Arte della fuga di Bach.
Nel luglio 1943 alla Moore School of Electrical Engineer dell'Università della Pennsylvania, situata a Philadelphia, si incominciò a costruire un computer che avrebbe segnato una vera e propria pietra miliare nella storia della computazione: l'ENIAC (Electronic Numerical Integrator and Computer).
Si trattava di un progetto top secret, il cui nome in codice era PX.
L'ENIAC viene ritenuto da alcuni il primo vero computer della storia, anche se forse il primato andrebbe attribuito al Colossus, attivato verso la metà di febbraio del 1944 e progettato dal matematico Max Newmann, ispiratosi ai lavori del padre dell'informatica, Alan Turing, di cui abbiamo parlato approfonditamente qui.
L'ENIAC costò circa 8.000 dollari e venne finanziato dall'esercito.
Misurava 30 metri di lunghezza e pesava 32 tonnellate.
Funzionava grazie a 17.468 valvole a vuoto che dissipavano così tanto calore che la temperatura della stanza in cui la macchina lavorava spesso e volentieri si innalzava sino a 50 °C.
L'ENIAC era in grado di memorizzare soltanto 20 numeri, ma il suo difetto principale consisteva nel fatto che per cambiare un programma bisognava riconfigurare i suoi circuiti, operazione che poteva durare anche svariati giorni.
Un ulteriore grosso problema del suddetto computer era il fatto che il tempo in cui funzionava correttamente era assai inferiore al tempo in cui era guasto.
Nonostante tutte queste problematiche non di poco conto, l'ENIAC fu utilizzato per 10 anni, compiendo in quel lasso di tempo più calcoli matematici di quelli realizzati fino ad allora nella storia dell'umanità.
E von Neumann?
Il suo contatto con l'ENIAC fu del tutto casuale.
Il matematico statunitense Herman Heine Goldstine (1913-2004) si arruolò nell'esercito all'inizio della Seconda Guerra Mondiale.
Lavorò con il grado di tenente nel BRL, ovvero il laboratorio di ricerca balistica di Aberdeen, nel Maryland.
Da esperto nella preparazione di tavole da tiro si era reso conto dell'impellente necessità di rendere automatici i noiosi e lunghi calcoli attraverso un qualche tipo di calcolatore elettronico.
Non sorprende dunque che costui accettò di fare da intermediario tra la Moore School (a Philadelphia), incaricata della costruzione dell'ENIAC, e Aberdeen.
Nell'estate del 1944, Goldstine incontrò per caso von Neumann nell'atrio della stazione ferroviaria di Aberdeen.
Goldstine non lo conosceva di persona, tuttavia aveva partecipato a diverse sue conferenze e decise perciò di avvicinarlo.
Gli argomenti iniziali della conversazione furono di poca importanza, sino a quando Goldstine non si lasciò sfuggire che stava lavorando alla costruzione di un nuovo computer.
A questo punto l'atteggiamento di von Neumann mutò improvvisamente e, secondo quanto racconta lo stesso Goldstine, gli fece il terzo grado.
Dallo stile delle domande, Golstine capì che aveva di fronte un esperto in quel campo, così decise di invitare von Neumann al centro di ricerche di Moore per metterlo direttamente in contatto con gli ingegneri John Mauchly e Prosper Eckert, coloro che si stavano occupando della progettazione dell'ENIAC.
Di fronte al nuovo computer, von Neumann chiese a Eckert la struttura logica del sistema, una domanda chiave affinché gli ingegneri dell'ENIAC gli aprissero le porte a una collaborazione duratura.
Von Neumann ragionò sulla possibilità di progettare un insieme di istruzioni che fossero un riflesso fedele di tutti i passaggi che si facevano con carta e penna nella risoluzione di un problema e che, a sua volta, tale insieme di istruzioni potesse venir memorizzato nella memoria centrale.
Per consentire che questo insieme di dati potesse entrare in un computer, bisognava dotarlo di una nuova unità, differente da quella dedicata ai calcoli, di modo che da un lato si potessero far entrare indistintamente dati e programmi e dall'altro raccogliere i risultati.
Un'idea questa di von Neumann che anticipò il concetto a noi molto familiare di software.
Pertanto, nel 1945, nel Laboratorio Nazionale di Los Alamos si incominciò a lavorare al progetto di un nuovo computer che avesse dei programmi memorizzati.
L'architettura di von Neumann corrisponde nientemeno che al concetto di programma memorizzato.
Oggi esistono computer con programmi memorizzati, per esempio una calcolatrice tascabile con cui è possibile eseguire una serie di calcoli complessi, ma con cui non si può scrivere un testo.
In un pc, invece, se abbiamo bisogno di un determinato programma che ci consenta di scrivere testi, è sufficiente installarlo e lavorarci sopra.
Ma non è stato sempre così.
Abbiamo infatti già osservato come nei primi computer, ENIAC compreso, cambiare programma significava cambiare la struttura, e per farlo si doveva realizzare uno schizzo con carta e penna per poi cambiare il cablaggio della macchina.
Von Neumann eseguì numerose tipologie di rifacimento del cablaggio al fine di rendere più scorrevoli le operazioni dell'ENIAC, tuttavia era conscio che per quanto ottimizzasse il sistema, avrebbe avuto sempre dei seri limiti.
La geniale ideale di von Neumann fu che i dati del programma, i quali potevano essere espressi in bit come 0 e 1, fossero memorizzati nella memoria insieme agli altri dati.
Ciò permetteva di modificare gli indirizzi di memoria e pure gli stessi programmi durante la loro esecuzione.
Gran parte dei computer moderni si basa proprio sulla suddetta architettura.
5 sono i componenti fondamentali di questa architettura:

1) CPU (o unità di lavoro o processore centrale) a sua volta suddivisa in:

- unità operativa, che comprende l'unità aritmetico-logica (ALU);
- unità di controllo.

2) Memoria;
3) Unità di input:
4) Unità di output;
5) Bus di sistema (un canale che collega tutti i componenti tra loro).

Vediamo brevemente gli aspetti fondamentali di tali componenti, incominciando dalla memoria.

 MEMORIA

La memoria è l'unità funzionale del computer che registra e recupera le istruzioni e i dati da eseguire.
Chiaramente tutte le informazioni immagazzinate in memoria sono rappresentate internamente mediante il sistema di numerazione binario.
In generale, quando ci si riferisce alla memoria di un computer, si sta parlando della memoria principale, detta anche RAM (Random Access Memory), dall'acronimo che indica la sua tipica modalità d'accesso.
La memoria ad accesso casuale presente le seguenti peculiarità:

  • Risulta suddivisa in unità a dimensione fissa chiamate celle. Ogni cella possiede un identificatore univoco denominato indirizzo. Questi indirizzi sono gli interi senza segno 0, 1, 2, ..., MAX;
  • Tutti gli accessi alla memoria sono destinati a uno specifico indirizzo, e occorre sempre estrarre o registrare una cella completa, cioè tutti i bit contenuti al suo interno. La cella è l'unità di accesso minima;
  • Il tempo necessario per estrarre o memorizzare il contenuto di una cella è lo stesso per tutte le celle della memoria.
Esiste poi la memoria di sola lettura ROM (Read-Only Memory), ossia una memoria ad accesso casuale in cui le informazioni sono state precaricate durante la produzione.
Tali informazioni non possono esser modificate o eliminate, ma soltanto lette.
La memoria ROM è usata per registrare importanti istruzioni e dati di sistema allo scopo di evitare che l'utente possa sovrascriverle per errore o intenzionalmente.
L'unità di memoria è formata da celle contenenti un numero fisso di cifre binarie.
Il numero di bit per cella viene chiamato dimensione di cella o ampiezza di memoria W.















Oggi i produttori di computer utilizzano una dimensione di cella standard di 8 bit, e questa unità di 8 bit viene universalmente chiamata byte.
Non sorprende dunque che il termine generico "cella" sia diventato abbastanza obsoleto e che ormai il termine più comune per indicare l'unità di base sia byte di memoria.
Non per questo va dimenticato però che il suddetto non è un termine generico, ma si riferisce a una cella che contiene esattamente 8 cifre binarie.
Con una dimensione di cella di 8 bit, il massimo valore intero senza segno che si può memorizzare in una singola cella è 255, un numero non molto grande.
Ergo i computer con dimensione di cella W = 8 fanno spesso uso di più celle per registrare un singolo valore di dati.
Ad esempio, molti computer usano 2 o 4 byte (16 o 32 bit) per memorizzare un intero e 4 o 8 byte (32 o 64 bit) per memorizzare un singolo numero reale.
In questo modo si ottiene l'intervallo di valore desiderato, ma con la necessità di diversi accessi alla memoria (invece di uno solo) per leggere un singolo elemento di dati.
Ogni cella di memoria nella RAM viene identificata da un indirizzo univoco senza segno 0, 1, 2, 3, ...
Se sono disponibili N bit per rappresentare l'indirizzo di una cella, allora l'indirizzo più piccolo è 0 mentre quello più grande è una stringa di N 1, cioè:


equivalente al valore 2N -1.
Ne consegue che l'intervallo di indirizzi disponibile su un computer è



con N designante il numero di cifre binarie disponibili per rappresentare un indirizzo.
In totale sono 2N celle di memoria, valore definito come dimensione di memoria massima o spazio di indirizzamento o ancora spazio degli indirizzi del computer.
Negli anni '60 e 70' valori tipici per N erano 16, 20, 22 e 24.
Oggi invece tutti i computer hanno almeno 32 bit di indirizzo che consentono di gestire fino a 232 (all'incirca 4 miliardi) byte di memoria.
La dimensione di memoria massima teorica è pari a 2N</sup>, ma un computer con N bit di indirizzo non è necessariamente fornito con 2N celle di memoria. 
Infatti questo valore indica semplicemente che la memoria del computer può essere espansa sino a 2N.
Per semplificare le cose, in informatica si utilizzano delle convenzioni per riferirsi alle dimensioni di memoria (e ad altri valori costituiti da potenze di 2).
Si sfrutta il fatto che i valori 210, 220, 230, 240, 250 risultano abbastanza vicini per ordine di grandezza rispettivamente a mille, un milione, un miliardo, mille miliardi e un milione di miliardi.
Possiamo schematizzare la questione in questo modo:







UNITÀ DI INPUT E DI OUTPUT

Le unità di ingressi/uscite (input/output, abbreviati I/O) sono dispositivi che permettono al computer di comunicare e interagire col mondo esterno, oltre che di memorizzare informazioni.
La memoria ad accesso casuale sopra descritta risulta volatile, cioè le informazioni vanno perdute quando viene interrotta l'alimentazione elettrica.
Senza una memoria a lungo termine, detta non volatile, le informazioni non potrebbero essere conservate dopo aver spento la macchina.
Per questo vengono utilizzati dispositivi di memoria di massa come dischi e nastri.
Tra le varie componenti di una macchina di von Neumann, i sottosistemi di I/O e di memoria di massa sono sicuramente quelli più specifici e variabili.
Infatti, differentemente dall'unità di memoria, l'unità di input/output non può essere rappresentata da un modello teorico ben definito.
Esistono decine di dispositivi di I/O e di memoria di massa differenti, prodotti da numerose aziende diverse e organizzati in maniera diversa, il che rende arduo effettuare generalizzazioni.
Sussistono però 2 principi cardine che trascendono le caratteristiche specifiche dei singoli dispositivi: i metodi di accesso I/O e il controllore I/O.
Esistono 2 tipologie principali di dispositivi di input/output:

1) quelli che rappresentano le informazioni in una forma leggibile dall'uomo (ad esempio, tastiera, schermo, stampante)
2) quelli che le rappresentano in forma leggibile dalla macchina (ad esempio, CD-ROM, DVD).

Una delle caratteristiche fondamentali di molti (ma non tutti) i dispositivi di input/output è la loro lentezza rispetto ad altre componenti del computer.
Non è raro che operazioni di I/O come la lettura di una riga su un monitor o la stampa di una pagina su una stampante siano da 3 a 6 ordini di grandezza più lente di qualsivoglia altro aspetto dell'attività del computer.
Se nel progettare un computer non si tenesse conto di cotal differenza, il tentativo di far comunicare fra loro componenti operanti su scale temporali del tutto incompatibili genererebbe gravi inefficienze.
I componenti ad elevata velocità rimarrebbero inattivi per prolungati intervalli di tempo, in attesa che le lente unità di I/O accettino o inviino i dati desiderati.
Sarebbe un po' come parlare alla normale velocità umana di circa 240 parole/min (4 parole/sec) a qualcuno che può rispondere con 1 parola ogni 8 ore, una differenza di 5 ordini di grandezza!
La soluzione per la spinosa questione consiste appunto nell'usare un controllore di I/O, ovvero un dispositivo simile a un piccolo computer specializzato, il cui ruolo è quello di gestire i dettagli delle operazioni di ingresso/uscita e di compensare qualsiasi differenza di velocità tra i dispositivi di I/O e le altre parti del computer.
Esso dispone di una piccola quantità di memoria, detta buffer di I/O, e di sufficienti capacità di controllo e logica di I/O per gestire le funzioni meccaniche del dispositivo di input/output, come la testina di lettura/scrittura, il meccanismo di avanzamento della carta e la visualizzazione sullo schermo.
Tra l'altro, è pure in grado di trasmettere al processore uno speciale segnale hardware, chiamato interrupt (interruzione), quando si effettua un'operazione di I/O.

UNITÀ ARITMETICO-LOGICA

L'unità aritmetico-logica (ALU) è il sottosistema che esegue operazioni matematiche e logiche quali addizione, sottrazione e confronto.
Sebbene l'ALU e l'unità di controllo si considerino a livello concettuale come separate, in tutti i computer moderni esse sono integrate in un unico componente, la CPU o processore.
L'ALU risulta formata da 3 parti:

1) i registi;
2) le interconnessioni tra le componenti;
3) la circuiteria.

Insieme, le suddette componenti vanno a costituire il data path (letteralmente "percorso dati").
Specifichiamo che un registro è una cella di memoria contenente gli operandi di un'operazione aritmetica e, quando l'operazione è completa, contiene il risultato.

UNITÀ DI CONTROLLO

La più importante caratteristica dell'architettura di von Neumann è come detto il programma memorizzato, una sequenza di istruzioni in linguaggio macchina memorizzate come valori binari.
È compito dell'unità di controllo:

1) prelevare/leggere (fetch) dalla memoria la prossima istruzione da eseguire;
2) decodificarla (decode), cioè determinare che cosa fare;
3) eseguirla (execute), inviando il comando appropriato all'ALU, alla memoria o ai controllori di I/O.

I 3 passaggi elencati vengono ripetuti fino a quando non si raggiunge l'ultima istruzione del programma, denotata tipicamente come HALT, STOP oppure QUIT, oppure si incorre in un errore fatale che gli impedisce di continuare (per esempio un codice operazione non lecito, un indirizzo di memoria inesistente, o una divisione per 0).
Il processo può essere descritto algoritmicamente nel seguente modo:

Finché non si incontra un'istruzione HALT o un errore fatale
         fase di fetch
         fase di decodifica
         fase di esecuzione
Fine ciclo

La suddetta ripetizione delle fasi di fetch/decodifica/esecuzione viene chiamata anche ciclo di von Neumann.
Va specificato che l'idea di memorizzare le istruzioni assieme ai dati ha un antecedente in un articolo pubblicato nel 1936 da Turing alla London Mathematical Society.
In questo veniva fornita una descrizione dettagliata della cosiddetta macchina computazionale universale (macchina di Turing universale), contenente sia dati che istruzioni con una capacità di memoria infinita.
È decisamente probabile che von Neumann fosse a conoscenza delle idee di Turing, giacché i 2 furono in contatto durante il 1936 e il 1937, quando Turing era all'Università di Princeton.
E non è tutto, nel 1935 Turing presentò il progetto all'Università di Cambridge.
Sicuramente sia il lavoro di von Neumann che quello di Turing si riferivano a computer con programmi memorizzati, tuttavia il contributo di von Neumann venne pubblicato prima e ciò spiega perché questo tipo di architettura porta unicamente il suo nome.
Per concludere la trattazione sull'architettura di von Neumann, ecco un'immagine che ben riassume la sua organizzazione:
















Ed ora passiamo all'Arte della fuga, BWV 1080 di Bach!
Il re Federico II di Prussia, durante un suo viaggio a Potsdam, richiese a Bach d'improvvisare una fuga su un soggetto da lui stesso suggerito.
In seguito Bach compose l'Offerta Musicale (Das Musikalische Opfer BWV 1079): una serie di canoni basati sul "tema regio" suggeritogli dal sovrano e dedicata per l'appunto a Federico stesso.
Di persona Bach aveva stupito il sovrano come geniale improvvisatore, cioè sostanzialmente come esecutore, tuttavia la sua musica doveva apparirgli difficile, complicata, pedantesca.
Un giudizio questo assai ricorrente a quei tempi, in cui la musica di Bach veniva considerata "gotica", nel senso di difficile, di involuta, alla stregua dei pinnacoli delle antiche cattedrali.
"Gotica" poi come contraria allo spirito ordinato, pulito, geometrico, che esigeva in qualsiasi creazione umana (perciò anche nella musica) il sigillo chiaro e inequivocabile della razionalità.
Al giorno d'oggi riteniamo che non ci sia stato artista più "razionale" di Bach, ma allora si scambiava la sua razionalità per astrattismo e inutile artifizio.
Jean-Jacques Rousseau, nella sua Lettera sulla musica francese, criticava aspramente "gli abusi o piuttosto l'abitudine di fughe, imitazioni, doppi disegni e altre bellezze arbitrarie e puramente convenzionali...atti di barbarie che sopravvivono come i portali delle nostre chiese gotiche".
Si può affermare con una certa sicurezza che Rousseau non conoscesse né l'Offerta musicale né l'Arte della fuga, tuttavia nelle sue parole sembra di leggere il fastidio di chi, trovatosi ad ascoltare quelle opere speculative, se ne sia addirittura spaventato.
Nel 1739 Johann Mattheson dettava le regole auree per comporre una bella melodia, che:
  • deve avere "un non so che" che la renda immediatamente familiare a chiunque; 
  • deve bandire da sé ogni forzatura;
  • dev'essere ispirata dalla natura e dall'uso;
  • deve rinunciare al corteggio indesiderato della "grande arte", ovvero contrappunto e annessi e connessi.
Mattheson, ma anche Telemann, furono in Germania i campioni dell'arte "facile" cui il pubblico si rivolgeva con approvazione.
Bach restava invece fedele all'arte "grande", e veniva perciò messo in disparte.
Anche i suoi figli assimilarono totalmente le "mode e costumi" dell'epoca, con particolare riferimento all'ultimo, Johann Christian.
Ma Johann Sebastian non cedette mai ai voleri del tempo, tutt'altro, più si avvicinava la metà del XVIII secolo, più la sua scrittura si fece ardita, articolata, vicina all'astrattismo della speculazione, piuttosto che alle lusinghe della bella melodia o della piacevolezza del timbro strumentale.
All'Arte della Fuga dedicò gli ultimi 2 anni della sua vita, lasciandola incompiuta, e forse non poteva mai essere compiuta, in quanto la riflessione sull'idea del contrappunto non poteva avere fine.
Emblema di pedanteria e goticismo, considerata dai contemporanei niente più che un manuale di tecnica contrappuntistica, il Novecento ha restituito a quest'opera il suo prestigioso carattere di eccezionale prodigio creativo di cui la storia non conosce eguali.
Una delle peculiarità di quest'opera sta nel fatto che Bach non ha precisato il mezzo esecutivo.
Il grande compositore ha voluto evidenziare l'assolutezza, la spiritualità di quello che considerò il suo supremo testamento, la sua risposta musicale a una specie di paradosso che fu il suo credo: "il fine ultimo del basso continuo e di tutta la musica deve essere la gloria di Dio e lo svago dell'anima".
Una gloria e uno svago che egli perseguì ancora negli ultimi giorni di vita, quando, ormai cieco, dettò al genero Johann Christoph Altnikol gli ultimi Corali per organo.
Proprio il fatto che le composizioni dell'Arte della fuga fossero state create senza rispettare un ordine particolare e senza l'assegnazione di un preciso strumento fu ciò che impressionò il giovane von Neumann, che vide in tal opera un processo di astrazione all'interno della musica stessa.
Di seguito il video dell'esecuzione integrale dell'Arte della Fuga da parte dell'Emerson String Quartet:



E siccome mi sembra giusto sottolineare quanto la musica classica possa essere ancora attualissima, concluderei con una canzone datata 2010 intitolata L'herbe tendre, eseguita dalla splendida voce di Julie Zenatti.
Trattasi di un meraviglioso brano adattato su un sottofondo costituito nientemeno che dal Prelude N.2 in C minor dal libro I del Clavicembalo ben temperato BWV 847 dello stesso Bach.



--------------------------------------------------------------------------------------
Fonti principali:

- Von Neumann, La teoria dei giochi e la matematica della negazione di Enrique Gracián Rodríguez
- Informatica di G. Michael Schneider e Judith L. Gersting
- I Classici della Musica, Johann Sebastian Bach a cura di Eduardo Rescigno

Nessun commento:

Posta un commento