# Non-Uniform Memory Access

Non-Uniform Memory Access (NUMA) è un'architettura di memoria sviluppata per i sistemi multiprocessore dove i tempi di accesso dipendono dalla posizione della memoria rispetto al processore. Nelle architetture NUMA un processore può accedere rapidamente alla propria memoria locale, più lentamente alle memorie degli altri processori o alla memoria condivisa.
L'architettura NUMA è il logico passo successivo delle architetture SMP. Uno dei primi sistemi con questo tipologia di architettura fu l'XPS100 della Honeywell Information Systems Italia negli anni 80 e fu poi anche sviluppata da Sequent e Data General durante gli anni novanta. Queste tecnologie vennero in seguito adottate da VMS e da molti sistemi Unix, parzialmente anche nell'architettura di Windows NT Server dopo la ver. 5.6 e successivi.

## Concetti basilari

Le moderne CPU sono molto più veloci delle memorie a cui accedono. All'inizio degli anni settanta quando iniziarono a diffondersi i primi supercomputer le memorie erano molto più veloci dei processori e quindi problemi di accesso alla memoria non si ponevano. Con il rapido incremento della frequenza di funzionamento delle CPU i tempi di accesso alla memoria divennero un problema sempre più impellente fino a diventare uno dei principali problemi delle attuali generazioni di processori. Molti sistemi sviluppati alla fine degli anni 80 e 90 si concentravano sull'ottenere sistemi di accesso alla memoria molto veloci piuttosto che unità di calcolo veloci dato che l'obiettivo dei sistemi era quello di poter trattare elevate quantità di dati.
La chiave per ottenere elevate prestazioni con i moderni supercomputer è quello di limitare l'accesso alla memoria a una limitata quantità di memoria molto veloce. Per realizzare questo vengono utilizzate cache di dimensioni sempre crescente all'interno dei processori che mantengono i dati utilizzati di frequente. Queste cache vengono aggiornate con algoritmi sempre più avanzati al fine di mantenere solo le informazioni utilizzate effettivamente di frequente. Questi metodi non sono in grado di compensare completamente il continuo aumento di memoria e di dimensione dei programmi e sistemi operativi che riducono le prestazioni delle cache. Nei sistemi multiprocessore questo diventa ancora più evidente dato che solo un processore può accedere alla memoria mentre gli altri processori se devono accedere alla memoria sono costretti ad attendere il loro turno.
L'architettura NUMA cerca di porre rimedio a questo problema fornendo a ogni processore una piccola zona di memoria ad accesso esclusivo e veloce in modo da evitare la creazione di colli di bottiglia. Nel caso di applicazioni che richiedono la condivisione di dati come nel caso di server e simili l'architettura NUMA migliora le prestazioni se si suddivide la memoria centrale in diversi banchi e si assegna ad ogni banco un numero ridotto di processori.
Naturalmente i dati non sono realmente separati nelle memorie dei singoli processori e se dei dati devono essere elaborati da più processori questo è possibile. In questo caso l'architettura NUMA prevede che il software o dei dispositivi hardware provvedano a spostare i dati da un banco a un altro. Questa copia dei dati rallenta i processori e quindi l'efficienza delle architetture NUMA dipende molto dai compiti svolti dal sistema.

## Coerenza delle cache e NUMA (ccNUMA)

Oramai qualsiasi processore è dotato di una piccola zona di memoria molto veloce e ad accesso esclusivo chiamata cache. Queste memorie migliorano notevolmente le prestazioni del sistema perché sfruttano il principio di località dei programmi, ma la loro gestione introduce un notevole carico di lavoro aggiuntivo all'architettura NUMA.
Sebbene semplice da progettare, un'architettura NUMA senza cache non viene normalmente implementata, date le scarse prestazioni del sistema. Un'architettura NUMA che non mantenga le cache coerenti sarebbe anch'essa semplice da progettare ma la sua programmazione sarebbe praticamente impossibile. Quindi tutte le architetture NUMA hanno al loro interno dei meccanismi hardware che provvedono a gestire la coerenza delle cache; queste architetture sono chiamate ccNUMA.
Questi sistemi normalmente utilizzano comunicazioni interprocesso tra i gestori delle cache che tengono traccia del fatto che più processori abbiano copie della stessa zona di memoria e questi provvedono a invalidare le cache se uno dei processori modifica una di queste zone di memoria controllate. Per questa ragione le architetture NUMA forniscono delle prestazioni scarse se i processori accedono alle stesse zone di memoria in rapida successione. I sistemi operativi che sopportano le architetture NUMA cercano di ridurre il problema allocando i processi in modo da sfruttare la divisione dell'architettura e fornendo algoritmi di gestione e di bloccaggio della memoria in modo da ridurre gli accessi contemporanei alla stessa zona di memoria.

## NUMA e cluster

L'architettura NUMA può essere vista come una versione ridotta di cluster di computer. L'aggiunta della paginazione della memoria virtuale a un sistema a cluster permette di emulare un'architettura NUMA anche se questa non esiste in hardware. Tuttavia questa soluzione è molto più lenta: la comunicazione interprocesso in un'architettura NUMA software è diversi ordini di grandezza più lenta di una comunicazione interprocesso in un'architettura NUMA hardware.