Parallelizzazione automatica

Da Wikipedia, l'enciclopedia libera.

In informatica la parallelizzazione automatica, o autoparalellizzazione, si riferisce alla conversione automatica da parte di compilatori di codice sequenziale in codice multi-threaded o vettoriale, o entrambi, in modo da utilizzare contemporaneamente tutte le unità di calcolo dei processori multi-core.

Questa operazione serve dunque ad incrementare le prestazioni in termini di conversione di codice in forma parallelizzata eliminando l'onere al programmatore di dover tenere conto di tutte le variabili che intervengono nella parallelizzazione manuale. Nonostante questa tecnica sia in sviluppo da un decennio, la completa parallelizzazione automatica resta una delle operazioni più complesse che un parser o una macchina virtuale devono eventualmente eseguire.

Descrizione[modifica | modifica sorgente]

Questa tecnica si concentra in particolare sui cicli, dato che questi occupano la CPU per un lungo tempo e compiono operazioni che spesso possono essere eseguite in modo parallelo. La parallelizzazione automatica, in questo caso, tenta di dividere due cicli in modo da lanciarli in esecuzione contemporaneamente su due CPU.

Tecniche[modifica | modifica sorgente]

Il compilatore in genere analizza il codice in due passate per poter rispondere alle seguenti domande:

  • È sicuro parallelizzare il ciclo? La risposta a questa domanda richiede una approfondita analisi delle dipendenze.
  • La parallelizzazione è efficace ai fini di una riduzione dei tempi di esecuzione ? La risposta a questa domanda richiede un modello di analisi piuttosto complicato a priori del comportamento del codice in esame.

Una prima analisi del compilatore esegue il controllo delle dipendenze, in modo da capire quale ciclo può essere separato dagli altri ed eseguito in modo indipendente. Una delle variabili difficili da considerare in questa fase è la condivisione della memoria primaria.

La seconda scansione invece cerca di capire quali cicli è effettivamente utile separare. La creazione di un thread crea inevitabilmente dell'overhead, una perdita di tempo che se il ciclo si rivela troppo breve può ridurre considerevolmente il tempo di esecuzione globale. Questa fase è molto complessa da eseguire a priori, in quanto è difficile sapere quanto lungo sarà il ciclo prima che questo sia effettivamente eseguito. Il compito è invece facilitato alle macchine virtuali, in quanto queste possono basarsi sulla storia passata del comportamento del codice.