# Tassonomia di Flynn

La tassonomia di Flynn è un sistema di classificazione delle architetture dei calcolatori. Nel 1966 Michael J. Flynn classifica i sistemi di calcolo a seconda della molteplicità del flusso di istruzioni e del flusso dei dati che possono gestire; in seguito questa classificazione è stata estesa con una sottoclassificazione per considerare anche il tipo di architettura della memoria.

## Categorie

In base a questa classificazione ogni sistema di calcolo rientra in una di queste categorie:
* SISD (Single Instruction Single Data)
* SIMD (Single Instruction Multiple Data)
** Processori vettoriali
** Array processor
** Array sistolici
* MISD (Multiple Instruction Single Data)
* MIMD (Multiple Instruction Multiple Data)
** Sistemi a memoria distribuita
*** MPP Massively Parallel Processing
*** COW Cluster Of Workstations
** Sistemi a memoria condivisa
*** UMA Uniform Memory Access
*** NUMA NonUniform Memory Access
**** NC-NUMA No Cache - NUMA
**** CC-NUMA Cache Coherent - NUMA
*** NORMA NO Remote Memory Access
*** COMA Cache only memory Access
** Macchine dataflow
** Macchine a riduzione
Nel 2003 la DEC ha sviluppato un nuovo tipo di CPU, detta asincrona, che elabora i dati sequenzialmente, ma senza clock. Essendo auto-controllate, un eventuale parallelismo di questi processori sarebbe al di fuori della classificazione. Questa logica di sviluppo ha comunque acceso un grosso dibattito tra gli ingegneri (vedi questo articolo in inglese).

## SISD

Nessun parallelismo: le operazioni vengono eseguite sequenzialmente, su un dato alla volta. È la classica architettura di von Neumann: i PC monoprocessore, ovvero i PC venduti nel periodo prima del 2010, sono basati su questa filosofia.

## SIMD

Alla classe SIMD appartengono le architetture composte da molte unità di elaborazione che eseguono contemporaneamente la stessa istruzione ma lavorano su insiemi di dati diversi. Generalmente, il modo di implementare le architetture SIMD è quello di avere un processore principale che invia le istruzioni da eseguire contemporaneamente ad un insieme di elementi di elaborazione che provvedono ad eseguirle. Il processore principale spesso è ospitato all'interno di un calcolatore convenzionale che provvede a supportare anche l'ambiente di sviluppo. I sistemi SIMD sono utilizzati principalmente per supportare computazioni specializzate in parallelo. Esempi più famosi di macchine SIMD: i supercomputer vettoriali, usati per particolari applicazioni (dove soprattutto si lavora su grandi matrici).

### Processori vettoriali

Questo tipo di processori, oltre ai normali registri e istruzioni scalari, contiene degli speciali tipi di registri (registri vettoriali) che possono contenere N valori contemporaneamente, ed ogni operazione che coinvolga uno di questi registri viene eseguita su tutti i valori in esso memorizzati. Affinché questo meccanismo sia efficiente è necessario che il collegamento da e verso la memoria sia molto veloce, cioè abbia una banda passante molto elevata: in questo tipo di macchine anche la memoria è organizzata in modo vettoriale, vale a dire strutturata in modo che sia possibile leggere o scrivere esattamente N valori contemporaneamente. Inoltre in genere è possibile specificare un altro registro vettoriale come destinazione dell'operazione vettoriale corrente, dove il risultato verrà ulteriormente manipolato.
Queste macchine sono programmabili con facilità (il parallelismo è gestito in maniera del tutto trasparente al programmatore), ma danno buone prestazioni solo nel caso di algoritmi con molte istruzioni vettoriali: sono particolarmente adatte per applicazioni di calcolo scientifico. Sono anche dette macchine a parallelismo temporale

### Array processor

Un array processor invece non ha affatto istruzioni scalari, ma solo vettoriali; è costituito da una unità di controllo (UC) che gestisce un array di processori (PE, Processor Element): i collegamenti fra PE e PE, e fra PE e memoria, sono di tipo matriciale, vale a dire che ogni PE comunica con i suoi quattro vicini, con la UC e con la memoria.
La UC legge le istruzioni, se sono scalari le esegue lei stessa, se sono vettoriali le invia a ogni PE che si occupa di un singolo dato dell'array, in parallelo: quando tutti i PE hanno terminato la UC passa all'istruzione successiva. Per questo un array processor viene considerato una macchina a parallelismo spaziale.
Le prestazioni di un array processor sono ancora più legate al tipo di operazione: è molto veloce solo quando opera su array e vettori.
Una evoluzione dell'array processor è la Connection Machine, che al posto dei normali PE introduce delle celle costituite da un PE e una memoria locale, connesse con una topologia ipercubica.

### Array sistolici

Gli array sistolici sono delle architetture che elaborano un flusso di dati che si muove in modo prevedibile e ritmico lungo uno specifico percorso durante la sua elaborazione. Sono utilizzati spesso nell'elaborazione dei segnali dato che i dati sono campionati con delle frequenze conosciute e devono subire delle elaborazioni predefinite che interessano tutti i dati. In questi array ogni elemento esegue una specifica elaborazione che dipende solamente dai dati di ingresso e dal suo stato interno. I dati elaborati sono posti in uscita dove un altro elemento provvederà a riceverli ed elaborarli. Le operazioni sono sincronizzate tramite un clock globale. Gli algoritmi eseguiti su questi array sono detti sistolici in analogia con il flusso sanguigno che provvede ad impulsi tramite percorsi predefiniti.

## MISD

La classe MISD, in cui più flussi di istruzioni (processi) lavorano contemporaneamente su un unico flusso di dati, non è stata finora utilizzata praticamente. È da notare che, mentre nella classe SIMD la granularità, ovvero la dimensione delle attività eseguibili in parallelo, è quella delle istruzioni, nella classe MISD e in quella MIMD la granularità è quella dei processi, programmi composti da più istruzioni.

## MIMD

Più istruzioni vengono eseguite contemporaneamente su più dati diversi. Sotto questa classificazione ricadono i cluster di computer, che negli ultimi anni stanno avendo una notevole diffusione.

### Sistemi a memoria distribuita

In questa categoria ricadono le macchine che assegnano ad ogni nucleo di calcolo (nodo) una propria memoria riservata. Se un nodo deve accedere ai dati memorizzati in altro nodo deve farne richiesta attraverso uno scambio di messaggi tra i nodi o tecniche analoghe.

#### Massively Parallel Processing

Le macchine MPP sono composte da centinaia di processori (che possono diventare anche centinaia di migliaia in alcune macchine) collegati da una rete di comunicazione. Le macchine più veloci del pianeta sono basate su queste architetture.

#### Cluster Of Workstations

Le architetture COW sono sistemi di elaborazione basati su classici computer collegati da reti di comunicazione. I cluster di calcolo ricadono in questa classificazione.

### Sistemi a memoria condivisa

In questa categoria ricadono le macchine dove più unità di calcolo pur eseguendo programmi differenti accedono alla stessa memoria. I sistemi SMP ricadono in questa categoria

#### Uniform Memory Access

Questi sistemi di elaborazione sono dotati di una memoria centralizzata che i processori utilizzano tramite un sistema a bus usualmente. La caratteristica fondamentale di questo sistema è il tempo di accesso alla memoria che è costante per ogni processore e per qualsiasi zona di memoria. Questo sistema è relativamente semplice da implementare ma non è molto scalabile. Questi sistemi al massimo gestiscono una dozzina di processori.

#### NonUniform Memory Access

Questi sistemi di elaborazione suddividono la memoria in una zona ad alta velocità assegnata singolarmente ad ogni processore ed una eventuale zona comune per lo scambio dei dati. Questi sistemi sono molto scalabili ma più complessi da sviluppare. Si dividono in due categorie:
* NC-NUMA: No Cache - NUMA
* CC-NUMA: Cache Coherent - NUMA

#### NORMA

NO-Remote Memory Access (NORMA) model
La memoria è distribuita fisicamente tra i processori (local memory). Tutte le memorie locali sono private e può accedervi solo il processore locale. La comunicazione tra i processori avviene tramite un protocollo di comunicazione per scambio di messaggi (message passing).

#### Cache Only Memory Access

Questa tipologia di elaboratori sono dotati solamente di memorie cache. Analizzando le architetture NUMA si è notato che queste mantenevano delle copie locali dei dati nelle cache e che questi dati erano memorizzati come doppioni anche nella memoria principale. Questa architettura elimina i doppioni mantenendo solo le memorie cache.

### Macchine dataflow

Le macchine a dataflow utilizzano un approccio innovativo nella programmazione. Il programma non è composto da una serie di istruzioni da eseguire sequenzialmente ma da un approccio data-driven. In sostanza le operazioni vengono eseguite solamente quando i dati per le elaborazioni sono disponibili. Non esiste un program counter che tiene traccia dello stato del programma.

### Macchine a riduzione

Le macchine a riduzione utilizzano un approccio simile a quello delle macchine dataflow ma utilizzano un punto di vista diverso. Invece di utilizzare un approccio data-driven utilizzano un approccio demand-driven. Questo approccio prevede che le computazioni vengano eseguite solamente quando vi è una richiesta dei risultati da elaborare. Anche in questa tipologia di macchina non vi è un program counter.