La campana.

Ci sono quelli che hanno letto questa notizia prima di te.
Iscriviti per ricevere articoli freschi.
E-mail
Nome
Cognome
Come vuoi leggere la campana
Senza spam.

Saul. 9 settembre 2015 alle 13:38

Attuazione dell'architettura multi-filettata motore di gioco

  • Blog di Intel.
  • Sviluppo del gioco
  • Programmazione parallela
  • Sviluppo del sito web
  • Trasferimento

Con l'avvento dei processori multi-core, è stato necessario creare un motore di gioco basato sull'architettura parallela. L'uso di tutti i processori di sistema - sia grafici (GP) che il Centro (CPU) - apre molte più opportunità rispetto a un motore a filettato unico sulla base del solo GP. Ad esempio, utilizzando più core della CPU, è possibile migliorare gli effetti visivi, aumentando il numero di oggetti fisici utilizzati nel gioco, oltre a raggiungere un comportamento più realistico dei personaggi implementando l'intelligenza artificiale avanzata (AI).
Considera le caratteristiche dell'attuazione dell'architettura multi-filettata del motore di gioco.

1. Introduzione

1.1. Panoramica

L'architettura multi-thread del motore del gioco consente di utilizzare le funzionalità di tutti i processori della piattaforma al massimo. Coinvolge parallelo a eseguire vari blocchi funzionali su tutti i processori disponibili. Tuttavia, non è così facile implementare uno schema simile. Elementi separati del motore di gioco spesso interagiscono con l'altro, che possono portare alla comparsa di errori mentre eseguito contemporaneamente. Per elaborare tali scenari nel motore, vengono forniti meccanismi speciali di sincronizzazione dei dati che escludono possibile blocco. Implementa anche i metodi per la sincronizzazione dei dati simultanei, a causa del quale è possibile ridurre al minimo il tempo di esecuzione.

Per capire i materiali rappresentati, è necessario comprendere bene nei metodi moderni di creare giochi per computer, supportando il multithreading per i motori di gioco o per migliorare le prestazioni dell'applicazione nel suo complesso.

2. Stato esecuzione parallelo

Lo stato di esecuzione parallelo è il concetto chiave di multithreading. Solo dividendo il motore di gioco ai singoli sistemi che corrono ciascuno nella sua modalità e praticamente non interagendo con il resto del motore, si può ottenere la massima efficacia del calcolo parallelo e ridurre il tempo necessario per la sincronizzazione. Isolare completamente le singole parti del motore, eliminando tutte le risorse comuni, non è possibile. Tuttavia, per le operazioni come l'ottenimento dei dati sulla posizione o sull'orientamento degli oggetti, i singoli sistemi possono utilizzare copie di dati locali e non risorse condivise. Ciò consente di minimizzare la dipendenza dei dati in diverse parti del motore. Le notifiche sulle variazioni dei dati generali eseguite da un sistema separato vengono trasmesse a Stato Manager, che li collocano in coda. Questa è chiamata modalità di messaggistica. Questa modalità si presume che completando l'esecuzione dell'attività, il sistema motore riceve notifiche sulle modifiche e aggiornare in modo appropriato i loro dati interni. Tale meccanismo consente di ridurre significativamente il tempo di sincronizzazione e la dipendenza dei sistemi l'uno dall'altro.

2.1 Stati di performance

Affinché il Gestore dello Stato esecuzione funzioni efficacemente, si consiglia di sincronizzare le operazioni su uno specifico impulso di clock. Ciò consente a tutti i sistemi di funzionare contemporaneamente. In questo caso, la frequenza degli orologi non deve necessariamente corrispondere al frame rate. Sì, e la durata dell'orologio potrebbe non dipendere dalla frequenza. Può essere selezionato in modo tale che un orologio corrisponda al tempo necessario per trasmettere un fotogramma (indipendentemente dalle sue dimensioni). In altre parole, la frequenza o la durata degli orologi determina l'implementazione specifica del Gestore statale. La figura 1 mostra "gratis" modalità passo-passo Lavorare in cui non è richiesto che tutti i sistemi abbiano completato l'esecuzione dell'operazione per lo stesso tatto. La modalità in cui tutti i sistemi completano l'esecuzione delle operazioni per un orologio sono chiamati una modalità "HARD" STEP-by-Step. È schematicamente rappresentato nella figura 2.


Figura 1. Stato delle prestazioni nella modalità passo-passo gratuita

2.1.1. Modalità passo-passo gratuita
In modalità passo-passo gratuita, tutti i sistemi funzionano continuamente per un periodo di tempo predeterminato richiesto per completare la parte successiva dei calcoli. Tuttavia, il nome "gratuito" non dovrebbe essere inteso letteralmente: i sistemi sono sincronizzati non in un momento arbitrario del tempo, sono solo "liberi" nella scelta del numero di orologi necessari per eseguire la fase successiva.
Di norma, in questa modalità, non è sufficiente inviare una semplice notifica di cambiamento di stato al manager di stato. È inoltre necessario trasferire i dati aggiornati. Ciò è dovuto al fatto che il sistema che ha cambiato i dati generali potrebbe essere nello stato di esecuzione, mentre un altro sistema in attesa di questo dato è già pronto per l'aggiornamento. In questo caso, è richiesta più memoria, come è necessario creare più copie di dati. Pertanto, il regime "gratuito" non può essere considerato una soluzione universale per tutte le occasioni.
2.1.2. Modalità rigida passo-passo
In questa modalità, i compiti di tutti i sistemi sono completati in un orologio. Tale meccanismo è più facile da implementare e non richiede il trasferimento dei dati aggiornati insieme alla notifica. Infatti, se necessario, un sistema può semplicemente richiedere nuovi valori in un altro sistema (ovviamente, alla fine del ciclo di esecuzione).
In modalità grave, è possibile implementare una modalità di funzionamento passo-passo Pseudo-Grade, distribuendo il calcolo tra diversi passaggi. In particolare, ciò potrebbe essere necessario per i calcoli dell'IA, in cui il primo tatto è calcolato dallo "obiettivo comune" iniziale, che è gradualmente specificato alle seguenti fasi.


Figura 2. Stato delle prestazioni nella modalità rigida passo-passo

2.2. Sincronizzazione dei dati

La modifica dei dati comuni da parte di più sistemi può portare a un conflitto di cambiamenti. In questo caso, nel sistema di messaggistica, è necessario fornire un algoritmo per la selezione del valore finale corretto. Esistono due approcci principali in base ai seguenti criteri.
  • Tempo: il valore finale diventa l'ultima modifica.
  • Priorità: il valore finale diventa il cambiamento effettuato dal sistema con la massima priorità. Se la priorità dei sistemi coincide, è anche possibile tenere conto del tempo di apportare modifiche.
Tutti i dati obsoleti (secondo qualsiasi criterio) possono semplicemente sovrascriverti o esclusi dalla coda delle notifiche.
Poiché il valore finale può dipendere dalla procedura per apportare modifiche, i valori relativi dei dati generali potrebbero essere molto difficili. In tali casi, dovrebbero essere utilizzati i valori assoluti. Quindi, quando si aggiornano i dati locali, il sistema può semplicemente sostituire i vecchi valori nuovi. La soluzione ottimale è scegliere valori assoluti o relativi a seconda della situazione specifica. Ad esempio, i dati generali, come la posizione e l'orientamento, devono avere valori assoluti, poiché sono importanti per la procedura per apportare modifiche. I valori relativi possono essere utilizzati, ad esempio, per il sistema di generazione di particelle, dal momento che tutte le informazioni sulle particelle sono memorizzate solo in esso stesso.

3. Motore

Quando si sviluppa un motore, l'attenzione è sulla flessibilità necessaria per espandere ulteriormente la sua funzionalità. Questo lo ottimizzerà per l'uso in condizioni di determinate restrizioni (ad esempio, memoria).
Il motore può essere diviso in due parti: framework e manager. Il framework (vedere la Sezione 3.1) include parti del gioco, che vengono replicate durante il processo di esecuzione, cioè esistono in diverse copie. Include anche elementi coinvolti nell'attuazione del principale ciclo di gioco. I manager (vedere la Sezione 3.2) sono responsabili di Singleton-Objects per l'esecuzione del componente logico del gioco.
Di seguito è riportato uno schema di un motore di gioco.


Figura 3. Architettura del motore generale

Si noti che i moduli di gioco funzionali o i sistemi non fanno parte del motore. Il motore li combina solo tra loro, agendo come un legante. Un'organizzazione modulare simile consente di caricare e scaricare i sistemi secondo necessità.

L'interazione del motore e dei sistemi viene effettuata utilizzando le interfacce. Sono implementati in modo tale da fornire l'accesso al motore alle funzioni di sistema e ai sistemi - ai gestori del motore.
Lo schema del motore dettagliato è presentato nell'appendice A, "Move Scheme".

Infatti, tutti i sistemi sono indipendenti l'uno dall'altro (vedere la sezione 2, lo "Stato di esecuzione simultanea"), cioè, possono eseguire azioni in parallelo senza influire sul funzionamento di altri sistemi. Tuttavia, qualsiasi modifica dei dati comporterà determinate difficoltà, dal momento che i sistemi dovranno interagire tra loro. Lo scambio di informazioni tra i sistemi è richiesto nei seguenti casi:

  • informare un altro sistema di modifica dei dati comuni (ad esempio, posizione o orientamento degli oggetti);
  • per eseguire le funzioni che non sono disponibili per questo sistema (ad esempio, il sistema AI si riferisce al sistema di calcolo delle proprietà geometriche o fisiche dell'oggetto per eseguire un test per l'attraversamento dei raggi).
Nel primo caso, il gestore di stato descritto nella sezione precedente può essere utilizzato per gestire le informazioni. (Per ulteriori informazioni su State Manager, vedere la Sezione 3.2.2, "State Manager".)
Nel secondo caso, è necessario implementare un meccanismo speciale che consentirà ai servizi di un sistema di utilizzare l'altro. Descrizione completa Questo meccanismo è indicato nella Sezione 3.2.3, "Service Manager".

3.1. FreymVork.

Il framework serve a unire tutti gli elementi del motore. Inizializza il motore, ad eccezione dei manager, le cui casi sono create a livello globale. Memorizza anche le informazioni sulla scena. Per ottenere una maggiore flessibilità, la scena è implementata come una cosiddetta scena universale, che contiene oggetti universali. Sono contenitori che combinano varie parti funzionali della scena. Per i dettagli, vedere la Sezione 3.1.2.
Il ciclo principale del gioco è anche implementato nel framework. Può essere presentato schematicamente come segue.


Figura 4. Ciclo del gioco principale

Il motore funziona nell'ambiente finestra, quindi nel primo passo del ciclo di gioco, è necessario elaborare tutte le finestre incompiute del sistema operativo. Se ciò non è fatto, il motore non risponderà ai messaggi del sistema operativo. Nel secondo passaggio, il pianificatore assegna attività utilizzando Task Manager. Questo processo è descritto in dettaglio nella sezione 3.1.1 di seguito. Successivamente, il Gestore statale (vedere la Sezione 3.2.2) invia informazioni sulle modifiche apportate dai sistemi della macchina, a cui può interessare. Nell'ultimo passaggio, a seconda dello stato dell'esecuzione, il framework determina se completare o continuare il funzionamento del motore, ad esempio, per andare alla scena successiva. Le informazioni sullo stato del motore sono memorizzate a Media Manager. Per i dettagli, vedere la Sezione 3.2.4.

3.1.1. Scheduler
Il pianificatore genera un segnale di riferimento di riferimento con una determinata frequenza. Se la modalità di test di riferimento richiede che l'operazione successiva inizia immediatamente dopo aver completato il precedente, senza attendere la fine dell'orologio, la frequenza può essere illimitata.
Da un segnale di clock, lo scheduler che utilizza il Task Manager traduce il sistema in modalità di esecuzione. Nella modalità passo-passo gratuita (Sezione 2.1.1), il pianificatore sonda il sistema per determinare quanti orologi saranno necessari per completare l'attività. Secondo i risultati del sondaggio, lo schedulatore determina quali sistemi sono pronti per l'esecuzione, e che completerà il lavoro in un orologio specifico. Lo scheduler può modificare il numero di clock se qualsiasi sistema richiede più tempo da eseguire. Nella dura modalità passo-passo (sezione 2.1.2), tutti i sistemi iniziano e completano l'esecuzione dello stesso orologio, quindi lo scheduler è in attesa quando tutti i sistemi sono completati.
3.1.2. Scena e oggetti universali
La scena e gli oggetti universali sono contenitori per funzionalità implementate in altri sistemi. Sono destinati esclusivamente per interagire con il motore e non eseguire altre funzioni. Tuttavia, possono essere ampliati per utilizzare le funzioni disponibili per altri sistemi. Ciò consente di ottenere una debole connessione. Infatti, la scena e gli oggetti universali possono utilizzare le proprietà di altri sistemi senza essere legati a loro. È questa proprietà che esclude la dipendenza dei sistemi l'uno dall'altro e dà loro l'opportunità di lavorare contemporaneamente.
Lo schema seguente mostra l'espansione di una scena universale e un oggetto.


Figura 5. Espansione della scena e dell'oggetto universale

Considera il principio del funzionamento delle estensioni nell'esempio seguente. Supponiamo che l'estensione della scena universale universale della scena venga espansa per utilizzare l'uso di proprietà grafiche, fisiche e altre proprietà. In questo caso, la parte "grafica" dell'espansione sarà responsabile dell'inizializzazione del display, e per l'attuazione delle leggi fisiche per i corpi solidi, come la gravità, è la sua parte "fisica". Le scene contengono oggetti, quindi la scena universale includerà anche diversi oggetti universali. Gli oggetti universali possono anche essere ampliati per essere migliorati per utilizzare l'uso di proprietà grafiche, fisiche e altre proprietà. Ad esempio, l'oggetto che disegna sullo schermo sarà implementato dalle funzioni di estensione grafica e il calcolo dell'interazione di corpi solidi è fisica.

Lo schema dettagliato dell'interazione del motore e dei sistemi è indicato nell'appendice B, il "regime di interazione del motore".
Va notato che la scena universale e l'oggetto universale sono responsabili della registrazione di tutte le sue "estensioni" nel manager statale, in modo che tutte le estensioni possano ricevere notifiche di modifiche apportate da altre estensioni (cioè da altri sistemi). Ad esempio, è possibile citare un'estensione grafica registrata per ottenere notifiche sui cambiamenti nella posizione e all'orientamento eseguito dall'espansione fisica.
Per i dettagli sui componenti del sistema, vedere la sezione 5.2, la sezione "Componenti del sistema".

3.2. Manager.

I manager gestiscono il lavoro del motore. Sono oggetti Singleton, cioè, il manager di ogni tipo è disponibile solo in un'istanza. Questo è necessario perché la duplicazione delle risorse dei dirigenti porterà inevitabilmente alla ridondanza e influenzerà negativamente le prestazioni. Inoltre, i manager sono responsabili dell'attuazione di funzioni comuni per tutti i sistemi.
3.2.1. Task Manager
Il Task Manager è responsabile della gestione delle attività di sistema nel pool di flusso. Per garantire il ridimensionamento n-multiplo ottimale e prevenire i flussi non necessari, eliminando i costi ingiustificati per cambiare attività nel sistema operativo, il pool di flusso crea un thread su ciascun processore.

Lo scheduler invia l'elenco delle attività al Task Manager per l'esecuzione, nonché informazioni sul completamento di quali compiti devono essere attesa. Riceve questi dati da diversi sistemi. Ogni sistema riceve solo un compito per l'esecuzione. Questo metodo è chiamato una decomposizione funzionale. Tuttavia, per l'elaborazione dei dati, ciascuna tali attività può essere suddivisa in una quantità arbitraria di sottotasks (decomposizione dei dati).
Di seguito è riportato un esempio della distribuzione dell'attività tra i thread per il sistema quad-core.


Figura 6. Esempio del pool di flusso utilizzato dal Task Manager

Oltre a elaborare le richieste di pianificazione per l'accesso alle attività principali, il Task Manager può funzionare in modalità di inizializzazione. Sonda costantemente i sistemi di ciascun thread in modo che possano inizializzare i data warehouse locali necessari per il lavoro.
I suggerimenti per l'implementazione del Task Manager sono forniti nell'appendice D, "Suggerimenti per l'implementazione delle attività".

3.2.2. Direttore di stato
Il gestore di stato è parte del meccanismo di messaggistica. Traccia modifiche e invia notifiche su di loro a tutti i sistemi che queste modifiche possono influenzare. Per non inviare notifiche non necessarie, lo stato Manager memorizza le informazioni su quali sistemi notificare in un caso particolare. Questo meccanismo è implementato sulla base del modello "Observer" (vedi Appendice C "," Osservatore (modello di progettazione) "). Se parli brevemente, questo modello. Assume l'uso dell'osservatore ", che è monitorato con eventuali modifiche all'oggetto e il ruolo dei media tra loro esegue il controller di modifica.

Il meccanismo funziona come segue. 1. L'Observer riporta il controller di modifica (o State Manager), le modifiche a quali soggetti che vuole tracciare. 2. L'argomento notifica al controller su tutte le sue modifiche. 3. Sul segnale quadro, il controller notifica l'osservatore sulle variazioni del soggetto. 4. L'osservatore invia una richiesta di ricevere dati aggiornati.

Nella modalità di esecuzione gratis passo-passo (vedere la sezione 2.1.1), l'implementazione di questo meccanismo è in qualche modo complicata. Innanzitutto, i dati aggiornati dovranno essere inviati con la notifica di modifica. In questa modalità, l'invio di richiesta non è applicabile. Infatti, se al momento della ricezione della richiesta, il sistema responsabile delle modifiche non completa l'esecuzione, non sarà in grado di fornire dati aggiornati. In secondo luogo, se un sistema non è ancora pronto per ottenere modifiche alla fine dell'orologio, il gestore di stato dovrà tenere i dati modificati fino a quando tutto il sistema registrato per ottenerli verrà allo stato di prontezza.

Nel framework, ci sono due manager State per questo: per gestire le modifiche a livello di scena e a livello dell'oggetto. Di solito i messaggi relativi a scene e oggetti sono indipendenti l'uno dall'altro, quindi l'uso di due gestori separati elimina la necessità di elaborare i dati non necessari. Ma se nella scena è necessario tenere conto dello stato di qualsiasi oggetto, può essere registrato per ottenere la ricezione delle notifiche sulle sue modifiche.

Per non eseguire la sincronizzazione non necessaria, il gestore di stato genera una coda delle notifiche di modifica separatamente per ciascun flusso creato dal Task Manager. Pertanto, quando si accede alla coda, non è richiesta alcuna sincronizzazione. La Sezione 2.2 descrive un metodo che può essere utilizzato per combinare le code dopo l'esecuzione.


Figura 7. Notifica dei cambiamenti interni nell'oggetto universale

Le notifiche di modifica non sono necessarie da inviare in sequenza. C'è un modo per la loro mailing parallela. Esecuzione di un'attività, il sistema funziona con tutti i suoi oggetti. Ad esempio, poiché gli oggetti fisici interagiscono tra loro, il sistema fisico li controlla per spostarsi, calcolare le nuove forze, ecc. Durante la ricezione di notifiche, l'oggetto di sistema non interagisce con altri oggetti del suo sistema. Interagisce con le estensioni associate ad essa. Ciò significa che gli oggetti universali sono ora indipendenti l'uno dall'altro e possono essere aggiornati simultaneamente. Questo approccio non esclude casi estremi che dovrebbero essere presi in considerazione durante il processo di sincronizzazione. Tuttavia, consente l'uso della modalità di esecuzione parallelo quando sembrava che fosse possibile solo in serie.

3.2.3. Services Manager.
Il servizio di assistenza fornisce accesso ai sistemi alle funzioni di altri sistemi che altrimenti non sarebbero disponibili. È importante capire che l'accesso alle funzioni viene effettuato utilizzando le interfacce e non direttamente. Anche le informazioni sulle interfacce di sistema sono conservate nel Gestore servizi.
Per eliminare le dipendenze dei sistemi l'uno dall'altro, ognuno di essi ha solo piccolo set Servizi. Inoltre, la possibilità di utilizzare un servizio è determinata non dal sistema stesso, ma il gestore dei servizi.


Figura 8. Gestione dei servizi di esempio

Il servizio di assistenza ha un'altra funzionalità. Fornisce ai sistemi l'accesso alle proprietà di altri sistemi. Le proprietà sono chiamate valori specifici di sistemi specifici che non vengono trasmessi nel sistema di messaggistica. Questa potrebbe essere una risoluzione dello schermo di estensione nel sistema grafico o nel valore della gravità in materia fisica. Il gestore dei servizi apre l'accesso a tali dati, ma non consente loro di controllarli direttamente. Posiziona cambiamenti nelle proprietà in un turno speciale e li pubblica solo dopo un'esecuzione coerente. Si noti che l'accesso alle proprietà di un altro sistema è abbastanza raro e non dovrebbe essere abusato. Ad esempio, potrebbe essere necessario abilitare e scollegare la modalità MESH frame nel sistema grafico dalla finestra della console o per modificare la risoluzione dello schermo su richiesta del lettore dall'interfaccia utente. Questa funzione è utilizzata principalmente per impostare i parametri che non cambiano dal fotogramma per fotogramma.

3.2.4. Gestione dell'ambiente
  • Il Gestore Media garantisce il funzionamento dell'ambiente di esecuzione del motore. Le sue funzioni possono essere suddivise nei seguenti gruppi.
  • Variabili: nomi e valori delle variabili comuni utilizzate da tutte le parti del motore. Tipicamente, i valori variabili sono definiti quando viene caricata la scena o determinate impostazioni personalizzate. Il motore e vari sistemi possono accedervi inviando la richiesta corrispondente.
  • Esecuzione: dati di esecuzione, come il completamento dell'esecuzione della scena o del programma. Questi parametri possono essere installati e richiedere sia i sistemi che il motore.
3.2.5. Gestione della piattaforma
Il gestore della piattaforma implementa l'astrazione per le sfide del sistema operativo e fornisce anche funzionalità aggiuntive oltre alla semplice astrazione. Il vantaggio di questo approccio è l'incapsulamento di diverse funzioni tipiche all'interno di una singola chiamata. Cioè, non devono essere implementati separatamente per ciascun elemento che causa, sovraccaricando i suoi dettagli sulle chiamate del sistema operativo.
Considera come esempio chiamare il gestore della piattaforma per scaricare la libreria di sistema dinamica. Non solo carica il sistema, ma riceve anche i punti di ingresso della funzione e provoca la funzione di inizializzazione della libreria. Il manager memorizza anche il descrittore della biblioteca e lo scarica dopo il completamento dell'operazione.

La piattaforma Manager è anche responsabile della fornitura di informazioni su un processore, come ad esempio supportato dalle istruzioni SIMD e per l'inizializzazione di una determinata modalità di funzionamento dei processi. Non è possibile utilizzare altre funzioni per la formazione di richieste di sistema.

4. Interfacce

Le interfacce sono mezzi di interazione tra framework, manager e sistemi. L'inquadratura e manager fanno parte del motore, in modo che possano interagire direttamente l'uno con l'altro. I sistemi al motore non appartengono. Inoltre, svolgono tutte funzioni diverse, che portano alla necessità di creare un singolo metodo di interazione con loro. Poiché i sistemi non possono interagire direttamente con i manager, è necessario fornire un altro metodo di accesso per loro. In questo caso, non tutte le funzioni dei manager devono essere aperte ai sistemi. Alcuni di loro sono solo framework disponibili.

Le interfacce definiscono un insieme di funzioni richieste per l'uso metodo standard Accesso. Elimina il quadro dalla necessità di conoscere i dettagli dell'attuazione di sistemi specifici, poiché può interagire con loro solo per mezzo di un determinato insieme di chiamate.

4.1. Interfacce soggetto e osservatore

Lo scopo principale delle interfacce del soggetto e dell'osservatore è la registrazione di quali osservatori modificano le notifiche di quali soggetti, oltre a inviare tali notifiche. La registrazione e la rottura della comunicazione con un osservatore sono caratteristiche standard per tutti i soggetti inclusi nell'attuazione della loro interfaccia.

4.2. Interfacce manager.

I manager, nonostante il fatto che siano oggetti di Singleton, sono direttamente disponibili solo per il framework. Altri sistemi possono accedere ai manager solo attraverso interfacce che rappresentano solo una parte della loro funzionalità generale. Dopo l'inizializzazione, l'interfaccia viene trasmessa a un sistema che lo utilizza per funzionare con determinate funzioni Manager.
Non esiste un'unica interfaccia per tutti i gestori. Ognuno di loro ha la sua interfaccia separata.

4.3. Interfacce di sistema

Per rendere il framework per accedere ai componenti del sistema, ha bisogno di interfacce. Senza sostenere ciascuno nuovo sistema Il motore dovrebbe essere implementato separatamente.
Ogni sistema include quattro componenti, quindi le interfacce devono essere quattro. Vale a dire: il sistema, la scena, l'oggetto e il compito. Descrizione dettagliata Vedere la Sezione 5, "Sistemi". Le interfacce sono strumenti per ottenere l'accesso ai componenti. Le interfacce di sistema consentono di creare ed eliminare scene. Le interfacce scene, a loro volta, consentono di creare e distruggere oggetti, nonché informazioni sull'attività principale del compito principale del sistema. L'interfaccia attività è utilizzata principalmente dal Task Manager quando si impostano le attività nel pool di flusso.
Poiché la scena e l'oggetto, come parte del sistema, devono interagire tra loro e con una scena universale e l'oggetto a cui sono legati, le loro interfacce sono anche create sulla base delle interfacce del soggetto e dell'osservatore.

4.4. Interfacce cambia

Queste interfacce servono a trasferire i dati tra i sistemi. Tutti i sistemi che apportano modifiche a un determinato tipo devono implementare tale interfaccia. Ad esempio, puoi portare la geometria. L'interfaccia geometrica include metodi per determinare la posizione, l'orientamento e l'elemento di scala. Qualsiasi sistema che apporta modifiche alla geometria deve implementare tale interfaccia in modo che non vi siano informazioni su altri sistemi per accedere ai dati modificati.

5. Sistemi

I sistemi fanno parte del motore che è responsabile per l'implementazione delle funzionalità di gioco. Eseguono tutti i compiti importanti, senza i quali il motore non avrebbe avuto senso. L'interazione tra il motore e i sistemi viene eseguita utilizzando le interfacce (vedere paragrafo 4.3, "Interfacce di sistema"). È necessario non sovraccaricare le informazioni del motore su tipi diversi Sistemi. Grazie alle interfacce, il processo di aggiunta di un nuovo sistema diventa molto più semplice, poiché il motore non ha bisogno di tenere conto di tutti i dettagli dell'attuazione.

5.1. Tipi

I sistemi motore possono essere suddivisi in diverse categorie predeterminate corrispondenti ai componenti standard del gioco. Ad esempio: geometria, grafica, fisica (collisione di solidi), audio, elaborazione di ingresso, AI e animazione.
I sistemi con funzioni non standard si riferiscono a una categoria separata. È importante capire che qualsiasi sistema che modifica i dati specifici della categoria dovrebbero essere a conoscenza dell'interfaccia di questa categoria, poiché il motore non fornisce tali informazioni.

5.2. Componenti del sistema

Per ciascun sistema, è necessario implementare diversi componenti. Ecco alcuni di loro: sistema, scena, oggetto e attività. Tutti questi componenti servono a interagire con diverse parti del motore.
Lo schema seguente mostra interazioni tra diversi componenti.


Figura 9. Componenti del sistema

Un circuito dettagliato dei collegamenti tra i sistemi motore è fornito nell'appendice B, il "schema e sistemi di interazione del motore".

5.2.1. Sistema
Il componente "Sistema" o semplicemente il sistema, è responsabile per l'inizializzazione delle risorse del sistema, che praticamente non cambierà durante il funzionamento del motore. Ad esempio, un sistema grafico analizza gli indirizzi delle risorse per determinare la posizione e l'accelerazione del download quando si utilizza la risorsa. Imposta anche la risoluzione dello schermo.
Il sistema è il punto di ingresso principale per il framework. Fornisce informazioni su di te (ad esempio, tipo di sistema), nonché metodi per la creazione e la rimozione delle scene.
5.2.2. Scena
La componente "Scena" o la scena del sistema, è responsabile della gestione delle risorse relative alla scena corrente. La scena universale utilizza scene di sistema per espandere la funzionalità attraverso l'uso delle loro funzioni. Ad esempio, una scena fisica può essere portata, che viene utilizzata quando si crea un nuovo mondo dei giochi e, quando inizializza la scena, determina le forze di gravità.
Le quinte prevedono metodi per la creazione e la distruzione di oggetti, nonché il componente "Attività" per elaborare la scena e il metodo di accesso ad esso.
5.2.3. Un oggetto
Il componente "oggetto" o l'oggetto di sistema, appartiene allo stadio ed è solitamente associato al fatto che l'utente vede sullo schermo. L'oggetto universale utilizza un oggetto di sistema per espandere la funzionalità, fornendo le sue proprietà come proprie.
Un esempio può servire come un'estensione geometrica, grafica e fisica di un oggetto universale per visualizzare un raggio di legno sullo schermo. Le proprietà geometriche includeranno la posizione, l'orientamento e la scala dell'oggetto. Per visualizzarlo, il sistema grafico utilizzerà una griglia speciale. E il sistema fisico gli darà le proprietà di un solido per il calcolo delle interazioni con altri organismi e le attuali forze di gravità.

In alcuni casi, nell'oggetto di sistema, è necessario considerare i cambiamenti nell'oggetto universale o una delle sue estensioni. A tale scopo, è possibile creare una connessione speciale che ti consentirà di tracciare le modifiche apportate.

5.2.4. Un compito
Il componente "Attività" o l'attività di sistema, viene utilizzato per elaborare la scena. L'attività riceve un comando per aggiornare la scena dal Task Manager. Questo è un segnale di avvio. funzioni di sistema Sugli oggetti della scena.
L'attività deve essere eseguita sulle sottotasks, distribuendoli anche utilizzando Task Manager a un numero ancora maggiore di flussi. Questo è un modo conveniente per ridimensionare il motore in diversi processori. Questo metodo è chiamato decomposizione dei dati.
Le informazioni su Modifica degli oggetti nel processo di aggiornamento delle attività di scena vengono trasmesse a State Manager. Per i dettagli sullo stato Manager, vedere la Sezione 3.2.2.

6. Combinazione di tutti i componenti

Tutti gli elementi sopra descritti sono interconnessi e fanno parte di un intero. Il lavoro del motore può essere diviso in diversi passaggi descritti nelle sezioni seguenti.

6.1. Inizializzazione in fase

Il lavoro del motore inizia con l'inizializzazione dei dirigenti e dei quadri.
  • Il framework chiama il caricatore di scena.
  • Definirendo quali sistemi di scena utilizzeranno, il downloader chiama il gestore della piattaforma per scaricare i moduli corrispondenti.
  • Il gestore della piattaforma carica i moduli corrispondenti e li trasmette al gestore dell'interfaccia, quindi li chiama per creare un nuovo sistema.
  • Il modulo restituisce il puntatore di caricamento a un'istanza del sistema che implementa l'interfaccia di sistema.
  • Il responsabile del servizio registra tutti i servizi che il modulo di sistema fornisce.


Figura 10. Inizializzazione dei gestori e dei sistemi motore

6.2. Scena del download della scena

Il controllo viene restituito dal caricatore che carica la scena.
  • Il bootloader crea una scena universale. Per creare istanze di scene di sistema, provoca interfacce di sistema, espandendo la funzionalità di una scena universale.
  • La scena universale determina quali dati possono modificare ciascuna scena di sistema e gli avvisi su cosa dovrebbe ricevere.
  • Confrontando le scene che eseguono determinate modifiche e si desidera ricevere avvisi su di esse, la scena universale trasmette queste informazioni al Gestore statale.
  • Per ogni oggetto scena, il bootloader crea un oggetto universale, quindi determina quali sistemi espanderanno l'oggetto universale. La corrispondenza tra gli oggetti di sistema è determinata dallo stesso schema utilizzato per le scene. Viene anche trasmesso al manager di stato.
  • Utilizzando le interfacce scene ottenute, il bootloader crea istanze di oggetti di sistema e li utilizza per espandere gli oggetti universali.
  • Lo scheduler richiede i dati dalle interfacce delle quinte sulle loro attività principali, in modo che nel processo di esecuzione di queste informazioni al Task Manager.


Figura 11. Inizializzazione della scena e oggetto universale

6.3. Fase ciclo Game.

  • Il gestore della piattaforma viene utilizzato per elaborare finestre e altri elementi necessari per la piattaforma corrente.
  • Quindi il controllo passa il pianificatore, che sta aspettando la fine dell'orologio per continuare a lavorare.
  • Alla fine del tatto in modalità gratis passo-passo, il pianificatore controlla quali sono state completate le attività. Tutti i compiti completati (ovvero, pronti per l'esecuzione) vengono trasmessi a Task Manager.
  • Lo scheduler determina quali attività saranno completate per il tatto corrente e li attende.
  • Nella modalità di esecuzione rigida passo-passo, queste operazioni vengono ripetute ogni orologio. Il pianificatore invia tutti i compiti al gestore e si aspetta che si esibiscano.
6.3.1. Esecuzione del task.
Il controllo va al Task Manager.
  • Forma una coda di tutti i compiti ricevuti, quindi, come appaiono i flussi gratuiti, inizia la loro esecuzione. (Il processo di esecuzione dell'attività varia a seconda dei sistemi. I sistemi possono funzionare solo con un'attività o per elaborare più attività dalla coda contemporaneamente, implementando così l'esecuzione parallela).
  • Nel processo di esecuzione dell'attività può funzionare con l'intera scena o solo con determinati oggetti, modificando i loro dati interni.
  • I sistemi dovrebbero ricevere notifiche di eventuali modifiche dei dati generali (ad esempio, posizione o orientamento). Pertanto, quando si esegue un'attività, una scena di sistema o un oggetto informano un osservatore di eventuali modifiche. In questo caso, l'osservatore agisce effettivamente come controller del cambiamento, che fa parte del manager di stato.
  • Il controller di modifica genera una coda delle notifiche di modifica per la successiva elaborazione. Ignora i cambiamenti che non riguardano questo osservatore.
  • Per utilizzare determinati servizi, l'attività si riferisce al servizio Service Manager. Il gestore dei servizi consente inoltre di modificare le proprietà di altri sistemi, inaccessibili per la trasmissione nel meccanismo di messaggistica (ad esempio, il sistema di immissione dei dati modifica l'espansione dello schermo: la proprietà del sistema grafico).
  • Le attività possono anche accedere a Media Manager per ottenere variabili di ambiente e modificare lo stato di esecuzione (sospensione dell'esecuzione, transizione verso la scena successiva, ecc.).


Figura 12. Task Manager e Attività

6.3.2. Aggiornamento dei dati
Dopo aver eseguito tutti i compiti dell'attuale clock, il ciclo di gioco principale si riferisce al gestore di stato per avviare il passaggio di aggiornamento dei dati.
  • Il gestore di stato provoca alternativamente ciascuno dei suoi controller inviare notifiche accumulate. Il controller controlla quali osservatori inviare notifiche sulle modifiche per ciascuno dei soggetti.
  • Quindi chiama l'osservatore desiderato e gli dice il cambiamento (la notifica include anche un puntatore all'interfaccia del soggetto). Nella modalità di esecuzione dettagliata gratuita, l'osservatore riceve i dati modificati dal controller di modifica, ma nella modalità di esecuzione del passo rigido, dovrebbe richiederli dal soggetto stesso.
  • In genere, gli osservatori interessati a ricevere notifiche sulle modifiche nell'oggetto di sistema sono altri oggetti di sistema associati allo stesso oggetto universale. Ciò consente di dividere il processo di apportare modifiche a diversi compiti che possono essere eseguiti in parallelo. Per semplificare il processo di sincronizzazione, tutte le estensioni associate dell'oggetto universale possono essere combinate in un'unica attività.
6.3.3. Controllare le prestazioni e l'uscita
La fase finale del ciclo di gioco è una validazione dello stato del runtime. Esistono diversi stati di questo tipo: lavoro, pausa, la prossima scena, ecc. Se lo stato "Work" è selezionato, verrà lanciata la seguente iterazione del ciclo. Lo stato "output" indica il completamento del ciclo, il rilascio di risorse e produzione dall'applicazione. Gli altri stati possono essere implementati, ad esempio "Pausa", "Scena successiva", ecc.

7. Conclusione

L'idea principale di questo articolo è riposta nella sezione 2, lo "stato di esecuzione parallela". Grazie alla decomposizione funzionale e alla decomposizione dei dati, è possibile implementare non solo il motore multithreading, ma anche la sua scalabilità a un numero ancora maggiore di nuclei in futuro. Per escludere i costi di sincronizzazione, continuando a supportare i dati aggiornati, utilizzare i gestori di stato oltre al meccanismo di messaggistica.

Il modello "Observer" è la funzione del meccanismo di messaggistica. È importante capire il principio del suo lavoro bene a scegliere il metodo ottimale della sua implementazione per il motore. In effetti, questo è il meccanismo dell'interazione tra diversi sistemi, che fornisce la sincronizzazione dei dati comuni.

Un ruolo importante nella distribuzione dei carichi viene riprodotto dalla gestione dei compiti. L'Appendice D fornisce consigli sulla creazione di un Task Manager efficace per il motore di gioco.

Come puoi vedere, il multithreading del motore di gioco può essere implementato grazie a una struttura e un meccanismo di messaggistica chiaramente definito. Con esso, è possibile aumentare significativamente la produttività dei processori moderni e futuri.

Appendice A. Schema del motore

L'elaborazione iniziale viene eseguita dal ciclo di gioco principale (vedi Fig. 4, "Principale ciclo del gioco").


Appendice B. Schema e sistemi di interazione del motore


Appendice C. Observer (modello di progettazione)

Il modello "Observer" è descritto in dettaglio nel libro "Design orientato all'accettazione. Modelli di design », E. Gamma, R. Helm, R. Johnson, J. Wlissides (" Modelli di design: elementi di software riutilizzabile orientato agli oggetti ", Gamma E., Helm R., Johnson R., Vlisside J.). In inglese, è stata pubblicata per la prima volta nel 1995 dalla casa editrice di Addison-Wesley.

L'idea principale di questo modello è la seguente: se alcuni elementi devono ricevere notifiche sulle modifiche in altri elementi, non sono necessarie per visualizzare l'elenco di tutte le possibili modifiche, cercando di trovare i dati richiesti in esso. Il modello prevede la presenza di un argomento e osservatore, che vengono utilizzati per inviare notifiche sulle modifiche. L'osservatore monitora eventuali modifiche al soggetto. Il controller di modifica funge da intermediario tra i due componenti di dati. Lo schema seguente illustra questa connessione.


Figura 13. Template "Observer"

Quanto segue descrive il processo di utilizzo di questo modello.

  1. Il controller di cambiamento registra l'osservatore e l'argomento, le notifiche di cui vuole ricevere.
  2. Il controller di cambiamento è in realtà un osservatore. Invece di un osservatore, insieme al soggetto, si registra lui stesso. Il controller di cambiamento memorizza anche la propria lista di osservatori e registrati con loro.
  3. Il soggetto contribuisce a un osservatore (cioè il controller della modifica) al suo elenco di osservatori che vogliono ricevere notifiche sulle sue modifiche. A volte indica inoltre il tipo di cambiamento che determina quali modifiche in cui è interessato l'osservatore. Ciò consente di ottimizzare il processo di invio di notifiche sulle modifiche.
  4. Modifica dei dati o dello stato, il soggetto avvisa l'osservatore attraverso il meccanismo di callback e trasmette informazioni sui tipi modificati.
  5. Il controller di modifica genera una coda delle notifiche di modifica e sta aspettando un segnale per distribuirli su oggetti e sistemi.
  6. Durante la distribuzione, il controller di cambiamento si rivolge agli osservatori reali.
  7. Gli osservatori richiedono informazioni sui dati modificati o un argomento dell'argomento (o portali insieme alle notifiche).
  8. Prima di rimuovere un osservatore o se non ha più bisogno di ricevere notifiche sull'argomento, elimina un abbonamento a questo argomento nel controller di modifica.
Ci sono molti in diversi modi Attuare la distribuzione delle attività. Tuttavia, è meglio mantenere il numero di flussi di lavoro pari al numero di processori di piattaforma logici disponibili. Cerca di non legare le attività a un flusso specifico. I tempi dei compiti di vari sistemi non sempre coincidono. Ciò può portare alla distribuzione del carico irregolare tra flussi di lavoro e influenzare l'efficacia. Per semplificare questo processo, utilizzare le librerie di gestione delle attività, come ad esempio

Avendo capito con la teoria del multithreading, considera l'esempio pratico - Pentium 4. Già nella fase di sviluppo di questo processore, Intel Engineers ha continuato a lavorare sul miglioramento delle sue prestazioni senza apportare modifiche all'interfaccia del programma. I cinque modi semplici sono stati considerati:

Aumentare la frequenza dell'orologio;

Posizionamento su un chip di due processori;

Introduzione di nuovi blocchi funzionali;

Estensione del trasportatore;

Usando il multithreading.

Il modo più ovvio per migliorare la velocità è aumentare la frequenza dell'orologio senza modificare altri parametri. Di norma, ogni modello del processore successivo ha una frequenza di clock leggermente superiore rispetto a quella precedente. Sfortunatamente, con un semplice aumento della frequenza dell'orologio, gli sviluppatori devono affrontare due problemi: un aumento del consumo di energia (che è rilevante per computer portatili e altri dispositivi di calcolo in esecuzione su batterie) e surriscaldamento (che richiede la creazione di dissipatori di calore più efficienti).

Il secondo metodo è il posizionamento sul chip di due processori - relativamente semplice, ma è associato al raddoppio dell'area occupata dal microcircuito. Se ogni processore viene fornito con la propria memoria della cache, il numero di microcircuiti sulla piastra è a fissaggio, ma significa anche raddoppiare il costo della produzione. Se per entrambi i processori c'è una memoria della cache comune, è possibile evitare un aumento significativo dell'area occupata, ma in questo caso si verifica un altro problema - la quantità di memoria della cache in termini di ciascun processore è dimezzata, e questo è inevitabilmente influenzato dalle prestazioni . Inoltre, se le applicazioni del server professionale sono in grado di utilizzare completamente le risorse di diversi processori, nei programmi desktop convenzionali il parallelismo interno è sviluppato in misura molto minore.

Anche l'introduzione di nuovi blocchi funzionali non è difficile, ma è importante mantenere l'equilibrio. Qual è il significato dei primi dieci blocchi di ALU, se il chip non può emettere comandi al trasportatore ad una velocità che consente di scaricare tutti questi blocchi?

Il trasportatore con un aumento del numero di passaggi in grado di separare i compiti in segmenti più piccoli ed elaborarli in brevi periodi di tempo, da un lato, aumenta le prestazioni, dall'altro, migliora le conseguenze negative di previsione errata delle transizioni, dei cacciatori, degli interrupt e altri eventi che violano i normali comandi di elaborazione del corso nel processore. Inoltre, per attuare pienamente le possibilità di un trasportatore espanso, è necessario aumentare la frequenza dell'orologio, e questo, come sappiamo, porta ad un aumento del consumo di energia e del trasferimento di calore.

Infine, è possibile implementare il multithreading. Il vantaggio di questa tecnologia è quello di introdurre un flusso software aggiuntivo che consente di entrare in vigore quelle risorse hardware che altrimenti sarebbero state semplici. Secondo i risultati degli studi sperimentali, gli sviluppatori Intel hanno scoperto che l'aumento dell'area del microcircuito del 5% nell'attuazione del multithreading per molte applicazioni fornisce un aumento del 25%. Il primo processore Intel con supporto per il multithreading è stato Heon 2002. Successivamente, a partire dalla frequenza di 3,06 GHz, il multithreading è stato introdotto nel Pentium 4. Intel Ruliere chiama l'implementazione di multithreading in Pentium 4 ipermacato (iperthreading).

  • Tutorial

In questo articolo, cercherò di descrivere la terminologia utilizzata per descrivere i sistemi che possono eseguire diversi programmi in parallelo, cioè multi-core, multiprocessore, multi-filettato. Diversi tipi di parallelismo nella CPU IA-32 sono apparsi in momenti diversi e in modo leggermente inconsistente. In tutto questo è abbastanza facile da confondere, in particolare considerando che i sistemi operativi nascondono accuratamente parti da programmi applicativi non troppo sofisticati.

Lo scopo dell'articolo è quello di dimostrare che con tutta la diversità di possibili configurazioni di sistemi multiprocessore, multi-core e multi-thread per programmi eseguiti su di essi, le opportunità vengono create sia per l'astrazione (ignorando le differenze) che per tenere conto delle specifiche (la possibilità di programmare la configurazione).

ATTENZIONE DEGLI SEGNI ®, ™, nell'articolo

Il mio spiega perché i dipendenti delle aziende dovrebbero usare i segni di copyright nelle comunicazioni pubbliche. In questo articolo, dovevano essere usati abbastanza spesso.

processore

Naturalmente, il termine più antico, più spesso usato e ambiguo è un "processore".

Nel mondo moderno, il processore è quindi (pacchetto) che compriamo in una bella scatola al dettaglio o non molto bella borsa OEM. Un'essenza indivisibile inserita nel connettore (presa) su scheda madre. Anche se non c'è connettore ed è impossibile rimuoverlo, cioè, se è strettamente saldato, questo è un chip.

I sistemi mobili (telefoni, tablet, laptop) e la maggior parte dei desktop hanno un processore. Le workstation e i server a volte vantano due o più processori su una scheda madre.

Il supporto per diversi processori centrali in un sistema richiede numerosi cambiamenti nel suo design. Almeno bisogno di fornirli connessione fisica (Fornire diverse prese sulla scheda madre), risolvere le questioni dei problemi di identificazione del processore (vedere in seguito in questo articolo, nonché la nota), coordinando l'accesso alla memoria e alla consegna degli interrupt (il controller di interruzione deve essere in grado di indirizzare gli interrupt in diversi processori ) E, naturalmente, supporto dal sistema operativo. I, Sfortunatamente, non riesco a trovare un documentario che menziona il momento di creare il primo sistema multiprocessore sui processori Intel, ma Wikipedia afferma che i sistemi informatici sequent hanno già fornito loro nel 1987 utilizzando i processori Intel 80386. Il supporto diffuso per diversi chip in un sistema diventa Disponibile a partire da Intel® Pentium.

Se ci sono diversi processori, ognuno di essi ha il proprio connettore sul tabellone. Ognuno di loro ha copie indipendenti complete di tutte le risorse, come registri, esecuzione di dispositivi, cache. Condividono la memoria complessiva - RAM. La memoria può connettersi a loro in modi vari e piuttosto non banale, ma questa è una storia separata che va oltre questo articolo. È importante che con qualsiasi scenario per i programmi eseguibili, l'illusione della memoria complessiva omogenea dovrebbe essere creata, accessibile da tutti i processori inclusi nel sistema.


Per decollo pronto! Scheda Desktop Intel® D5400XS

Nucleo

Storicamente, il multi-core in Intel IA-32 è apparso in seguito Intel® Hyperthreading, ma in una gerarchia logica, va dopo.

Sembrerebbe che se ci siano più processori nel sistema, allora le sue prestazioni (su compiti che possono utilizzare tutte le risorse). Tuttavia, se il costo delle comunicazioni tra di loro è troppo grande, l'intera vincente del parallelismo viene uccisa da lunghi ritardi nel trasmettere dati comuni. Questo è ciò che è osservato nei sistemi multiprocessore - sia fisicamente che logicamente, sono molto lontani l'uno dall'altro. Per una comunicazione efficace in tali condizioni, è necessario inventare pneumatici specializzati, come Intel® Quickpath Interconnection. Consumo energetico, dimensioni e il prezzo della decisione finale, ovviamente, non diminuiscono da tutto questo. L'elevata integrazione del componente - schemi che eseguono parti del programma parallelo dovrebbero venire in soccorso, è necessario alzarsi l'un l'altro, preferibilmente su un cristallo. In altre parole, diversi processori dovrebbero organizzarsi diversi kernels., in tutti gli identici l'uno all'altro, ma lavorando in modo indipendente.

I primi processori IA-32 multi-core da Intel sono stati presentati nel 2005. Da allora, il numero medio di nuclei in server, desktop e ora piattaforme mobili sta crescendo costantemente.

A differenza di due processori singoli in un unico sistema, separando solo la memoria, due nuclei possono anche avere cache comuni e altre risorse responsabili dell'intraagimento con la memoria. Molto spesso, le cache del primo livello rimangono private (ogni kernel), mentre il secondo e il terzo livello può essere sia generale che separato. Tale organizzazione del sistema riduce i ritardi nella consegna dei dati tra i nuclei adiacenti, specialmente se lavorano su un compito comune.


Microsinks del processore Intel a quattro core con il nome del codice Nehalem. I kernel separati sono evidenziati, la cache totale di terzo livello, nonché i collegamenti QPI ad altri processori e il controller di memoria complessivo.

Iperpot.

Fino a circa 2002, l'unico modo per ottenere il sistema IA-32 in grado di eseguire due o più programmi in parallelo, è stato quello di utilizzare sistemi multiprocessore. Nella linea Intel® Pentium® 4, così come la linea Xeon con il nome del codice Foster (NetBurst), viene presentata una nuova tecnologia - HyperTrons o Hyperpotions - IperThreading Intel® (di seguito HT).

Non c'è niente di nuovo sotto il sole. HT è un caso speciale che in letteratura è indicato come multithreading simultaneo (multithreading simultaneo, SMT). In contrasto con i nuclei "reali" che sono copie pieni e indipendenti, nel caso di HT in un processore, solo una parte dei nodi interni è duplicata, responsabile principalmente per lo stoccaggio dello stato architettonico - registri. I nodi esecutivi responsabili dell'organizzazione e dell'elaborazione dei dati rimangono in singolare, e in qualsiasi momento usano un massimo di uno dei flussi. Come il kernel, iperpotions sono divisi dai cache, ma a partire da quale livello dipende dal sistema specifico.

Non cercherò di spiegare tutti i pro e i contro dei disegni con SMT in generale e da HT in particolare. Un meraviglioso lettore può trovare una discussione abbastanza dettagliata sulla tecnologia in molte fonti, e, naturalmente, in Wikipedia. Tuttavia, noterò quanto segue momento importanteSpiegare le limitazioni correnti sul numero di iperpotioni in prodotti reali.

Restrizioni del flusso
Quando è la presenza di "disonesto" multi-core sotto forma di ht giustificato? Se un flusso di applicazioni non è in grado di caricare tutti i nodi di esecuzione all'interno del kernel, possono essere "presi in prestito" su un altro flusso. È in genere per le applicazioni aventi " collo di bottiglia»Non nei calcoli, ma quando si accede ai dati, si generano spesso missili della cache e costretti a aspettarsi che i dati di consegnare i dati dalla memoria. In questo momento, il kernel senza HT sarà costretto a inattivo. La presenza di HT consente di passare rapidamente i nodi di esecuzione gratuiti a un altro stato architettonico (perché è solo duplicato) ed esegui le sue istruzioni. Questo è un caso particolare di accettazione chiamato latenza che si nasconde, quando una lunga operazione, durante la quale le risorse utili sono inattive, sono mascherate da parallelo eseguendo altre attività. Se l'applicazione ha già un alto grado di riciclaggio delle risorse del kernel, la presenza di iperpotioni non consentirà di ottenere l'accelerazione - qui è necessario nuclei "onesti".

Scenari di lavoro tipici per applicazioni desktop e server progettate per le architetture della macchina scopo generale, avere il potenziale per il parallelismo implementato usando HT. Tuttavia, questo potenziale è "speso" rapidamente. Forse per questo motivo, quasi tutti i processori IA-32, il numero di iperpotioni hardware non supera i due. Sugli script tipici, la vittoria dall'uso di tre e più iperpotioni sarebbe piccola, ma la perdita della dimensione del cristallo, il suo consumo energetico e il suo valore è significativo.

Un'altra situazione è osservata su compiti tipici eseguiti su sceneggiatori video. Pertanto, queste architetture sono caratterizzate dall'uso della tecnologia SMT con un numero maggiore di fili. Poiché Intel® Xeon PHI coprocesses (presentato nel 2010) sono ideologicamente e genealogicamente vicino alle schede video, possono essere quattro L'ipertensione su ciascun kernel è unica per la configurazione IA-32.

Processore logico

Dei tre "livelli" del parallelismo (processori, kernels, iperpot), alcuni o anche tutto ciò che potrebbe mancare in un particolare sistema. Questo è influenzato impostazioni del BIOS (Multi-core e multithreading sono disconnessi in modo indipendente), le funzioni di microarchitettura (ad esempio, HT era assente in Intel® Core ™ Duo, ma è stato restituito con il rilascio di Nehalem) ed eventi durante il funzionamento del sistema (i server multiprocessore possono spegnere i processori rifiutati in caso di malfunzionamenti e continuare a "volare" sul restante). In che modo lo zoo del parallelismo multilivello sarà visto dal sistema operativo e in definitiva applicazioni applicate?

Successivamente, per comodità, indiciamo il numero di processori, kernel e flussi in un sistema a tre vie ( x., y., z.), dove x. - Questo è il numero di processori, y. - numero di nuclei in ciascun processore e z. - Il numero di iperpotioni in ogni kernel. Quindi, chiamerò questa tripla topologia - Termine stabilito, poco che ha con una sezione di matematica. Composizione p. = xyz. Determina il numero di entità chiamate processori logici Sistemi. Determina il numero totale di contesti indipendenti di processi applicati nel sistema con una memoria condivisa eseguibile in parallelo, che sistema operativo Costretto a prendere in considerazione. Dico "forzato", perché non può gestire la procedura per l'esecuzione di due processi su vari processori logici. Ciò vale anche per iperpotizioni: sebbene funzionino "costantemente" su un nucleo, l'ordine specifico è dettato dall'attrezzatura e non è disponibile per monitorare o gestire i programmi.

Molto spesso, il sistema operativo si nasconde dalle applicazioni finali. Caratteristiche della topologia fisica del sistema su cui è in esecuzione. Ad esempio, tre seguenti topologie: (2, 1, 1), (1, 2, 1) e (1, 1, 2) - OS saranno rappresentate come due processori logici, anche se il primo di loro ha due processori, il Secondo uno - due nuclei, e il terzo è solo due flussi.


Windows Task Manager mostra 8 processori logici; Ma quanto è in processori, chilometri e iperpot?


Linux Top mostra 4 processori logici.

È abbastanza conveniente per i creatori di applicazioni applicate - non devono affrontare spesso insignificanti per loro caratteristiche dell'attrezzatura.

Definizione del software di topologia

Naturalmente, l'astrazione della topologia in un unico numero di processori logici in alcuni casi crea un motivo per confusione e incomprensioni (nelle controversie internet calde). Le applicazioni computazionali che desiderano spremere le prestazioni massime del ferro richiedono un controllo dettagliato sul luogo in cui verranno posizionati i loro flussi: più vicini l'uno all'altro su iperpot vicini o viceversa, via su diversi processori. La velocità di comunicazione tra i processori logici nella composizione di un kernel o del processore è significativamente superiore alla velocità di trasferimento dei dati tra i processori. La possibilità di disomogeneità nell'organizzazione memoria ad accesso casuale Complica anche l'immagine.

Le informazioni sulla topologia del sistema nel suo complesso, nonché la posizione di ciascun processore logico in IA-32 è disponibile utilizzando l'istruzione CPUID. Dall'apparenza dei primi sistemi multiprocessore, lo schema di identificazione dei processori logici si è espanso più volte. Ad oggi, la sua parte è contenuta in fogli 1, 4 e 11 CPUID. Quale delle lenzuola dovrebbe essere visualizzata, è possibile determinare dal seguente diagramma a blocchi prelevato dall'articolo:

Non stancerò tutti i dettagli delle singole parti di questo algoritmo. Se sei interessato, allora questo può essere dedicato alla parte successiva di questo articolo. Partirerò il lettore del lettore a, in cui questa domanda è comprensibile il più dettagliato del tutto il possibile. Qui, per prima cosa descriverò brevemente ciò che è APIC e come è associato alla topologia. Quindi considerare il lavoro con un foglio 0xb (undici in numeri decimali), che è attualmente l'ultima parola nella "costruzione di spike".

ID APIC
APIC locale (Controller di interruzione programmabile avanzato) è un dispositivo (ora incluso nel processore), che è responsabile del lavoro con interrupt, che viene in un processore logico specifico. Ogni processore logico ha il proprio apice. E ognuno di loro nel sistema dovrebbe avere significato unico ID APIC. Questo numero viene utilizzato dai controller di interrupt per affrontare quando si forniscono messaggi e tutti gli altri (ad esempio, il sistema operativo) - identificare i processori logici. Le specifiche per questo controller di interruzione si sono evolute, passando dal chip Intel 8259 PIC tramite Dual Pic, APIC e XAPIC a X2APIC.

Attualmente, la larghezza del numero memorizzata in ID APIC ha raggiunto un intero 32 bit, anche se in passato era limitato a 16 anni, e anche prima - solo 8 bit. Oggi, i resti dei vecchi tempi sono sparsi in tutto il CPUID, ma tutti i 32 bit di ID APIC sono restituiti a CPUID.0XB.EDX. Su ciascun processore logico, eseguire in modo indipendente l'istruzione CPUID, tornerà al suo valore.

Riprese i legami correlati
L'ID APIC stesso non parla nulla della topologia. Per scoprire quali due processori logici sono all'interno dello stesso fisico (I.e. ", fratelli" con iperthms), quali due sono all'interno di un singolo processore, e che sono anche affatto in diversi processori, è necessario confrontare i loro valori ID APIC. A seconda del grado di parentela, alcuni dei loro bit coincidono. Queste informazioni sono contenute nella console di CPUID.0XB, che sono codificate utilizzando l'operando in ECX. Ognuno di loro descrive la posizione del campo di bit di uno dei livelli di topologia in EAX (più precisamente, il numero di bit che devono essere spostati nell'ID APIC a destra per rimuovere i livelli di topologia inferiore), così come il Tipo di questo livello - iperpotioni, un nucleo o processore, in ECX.

I processori logici che si trovano all'interno di un singolo nucleo coincidono tutti i bit ID APIC tranne il campo SMT. Per i processori logici situati in un processore, tutti i bit eccetto i campi Core e SMT. Dal momento che il numero di sublletters in CPUID.0XB può crescere, questo schema ti consentirà di mantenere una descrizione di topologie e con un livello più livelli se c'è bisogno di in futuro. Inoltre, sarà possibile introdurre livelli intermedi tra quelli esistenti.

Un'importante conseguenza dell'organizzazione di questo schema è che nel set di tutti gli ID APIC di tutti i processori logici del sistema possono essere "fori", cioè. Non andranno sequenzialmente. Ad esempio, in un processore multi-core con OFF HT, tutti gli ID APIC possono essere ben noti, dal momento che il bit più giovane responsabile della codifica del numero iperpoop sarà sempre zero.

Noi noto che cpuid.0xb non lo è l'unica fonte di Informazioni sui processori logici disponibili per il sistema operativo. L'elenco di tutti i processori accessibile ad esso, insieme ai loro valori ID APC, è codificato nella tabella Madt ACPI.

Sistemi operativi e topologia

I sistemi operativi forniscono informazioni sulla topologia dei processori logici alle applicazioni utilizzando le proprie interfacce.

In Linux, le informazioni sulla topologia sono contenute in Pseudo-file / proc / cpuinfo, nonché l'uscita del comando DMIDECODE. Nell'esempio seguente, filtro il contenuto di CPUInfo su un sistema a quattro core senza HT, lasciando solo le voci relative alla topologia:

Testo nascosto

[Email protetto]: ~ $ Cat / proc / cpuinfo | Grep "Prosessor \\ | fisico \\ ID \\ | Fishys \\ ID \\ | I fratelli \\ | | core \\ | Core \\ | | Apicid" Processore: 0 ID fisico: 0 Sìblings: 4 ID Core: 0 CPU Core: 2 Apicid: 0 Apicid iniziale: 0 Processore: 1 ID fisico: 0 Sìblings: 4 ID Core: 0 CPU Core: 2 Apicid: 1 Apicid iniziale: 1 Processore: 2 ID fisico: 0 fratelli: 4 ID nucleo: 1 CPU Core: 2 Apicid: 2 Apicide iniziale: 2 Processore: 3 ID fisico: 0 SIBLINGS: 4 ID Core: 1 CPU Core: 2 Apicid: 3 Apicid iniziale: 3

La topologia FreeBSD è riportata attraverso il meccanismo di Systl nella variabile Kern.sched.topology_Spec sotto forma di XML:

Testo nascosto

[Email protetto]: ~ $ sysctl kern.sched.topology_spec kern.sched.topology_spec: 0, 1, 2, 3, 4, 5, 6, 7 0, 1, 2, 3, 4, 5, 6, 7 0, 1 Gruppo di thread.Gruppo SMT. 2, 3 Gruppo di thread.Gruppo SMT. 4, 5 Gruppo di thread.Gruppo SMT. 6, 7 Gruppo di thread.Gruppo SMT.

In MS Windows 8, le informazioni sulla topologia possono essere visualizzate nel Task Manager Task Manager.

Per industria delle informazioni L'inizio del XXI secolo ha coinciso con i turni che possono essere descritti come "tettonici". I segni di una nuova era dovrebbero includere l'uso di architetture orientate ai servizi (architettura orientata al servizio, SOA), configurazioni del cluster e molti altri, compresi i processori multi-core. Ma, naturalmente, la causa fondamentale di ciò che sta accadendo è lo sviluppo della fisica del semiconduttore, la conseguenza della cui è diventata un aumento del numero di elementi logici per area dell'unità, che obbedisce la legge di Gordon Moore. Il numero di transistor sul cristallo è già calcolato da centinaia di milioni e supererà presto la miliardi di frontiera, come risultato della quale la legge nota della dialettica si manifesta inevitabilmente con il rapporto di cambiamenti quantitativi e qualitativi. Nelle condizioni modificate, una nuova categoria arriva alla ribalta complessitàe i sistemi diventano complessi e sul livello micro-livello (processori) e sul livello macro (sistemi di informazione societaria).

In una certa misura, ciò che sta accadendo nel mondo del computer moderno può essere paragonato alla transizione evolutiva che si è verificata milioni di anni fa, quando apparvero organismi multicellulari. Nel momento in cui la complessità di una cella ha raggiunto un certo limite, e la successiva evoluzione è andata lungo il percorso di sviluppo della complessità infrastrutturali. Lo stesso succede con sistemi informatici: la complessità di un nucleo del processore, così come l'architettura corporativa monolitica sistemi di informazione Raggiunto un certo massimo. Ora il livello macro è la transizione da sistemi monolitici a componenti (o composti da servizi), e l'attenzione degli sviluppatori si concentra sul software dell'infrastruttura dello strato intermedio e le nuove architetture del processore vengono visualizzate sul micro livello.

Letteralmente per lo meno, l'idea della complessità ha cominciato a perdere il buon senso, trasformando in un fattore indipendente. A questo proposito, la complessità non è ancora completamente compresa, e l'atteggiamento nei confronti non è completamente definito, anche se, stranamente, da quasi 50 anni c'è una disciplina scientifica separata, che è anche chiamata "la teoria dei sistemi complessi". (Ricordiamo che nella teoria del "complesso" ha chiamato il sistema, i cui componenti individuali sono combinati con un metodo non lineare; tale sistema non è solo la somma dei componenti, come accade in sistemi lineari.) Si può solo essere Sorpreso che la teoria dei sistemi non sia ancora percepita da tali specialisti e aziende, l'attività di cui li conduce alla creazione di questi sistemi complessi mediante tecnologia dell'informazione.

Architettura "bottiglia gola" von neymanan

Sul micro livello, un analogo della transizione da organismi a cellule singole a multicellulare può essere la transizione dai processori singoli a multi-core (multiprocessori del chip, CMP). CMP dà una delle possibilità di superare la debolezza congenita dei moderni processori - la "gola della bottiglia" dell'architettura von Neymanan.

Questo è ciò che John Bacik ha detto alla cerimonia di presentazione del premio Tyorov nel 1977: "Cos'è un computer su sfondo nimanan? Quando 30 anni fa, John Von Neuman e altri hanno offerto la loro architettura originale, l'idea sembrava elegante, pratica e consentendo di semplificare la soluzione di un certo numero di compiti di ingegneria e programmazione. E anche se nel passato, le condizioni che esistevano al momento della sua pubblicazione sono state radicalmente cambiate, identifichiamo le nostre idee sui computer con questi vecchi concetti. Nella presentazione più semplice, il computer nimaniano è composto da tre parti: questo è un processore centrale (CPU o CPU), memoria e collegamento del loro canale, che serve a scambiare dati tra la CPU e la memoria e le piccole porzioni (solo da una parola). Suggerisco di chiamare questo canale "sfondo bottiglia bottiglia di bottiglia neymanan. Sicuramente ci deve essere una soluzione meno primitiva che pompare una quantità enorme di dati attraverso una "stretta gola della bottiglia". Tale canale non crea non solo un problema per il traffico, ma è anche una "bottiglia intelligente della gola", che impone il pensiero del "insalata" dei programmatori, non permettendo di discutere in categorie concettuali più elevate. "

La più grande fama di Bakusa ha portato la creazione nella metà degli anni '50 del linguaggio Fortran, che per diversi decenni è stato il mezzo più popolare per creare programmi di regolamento. Ma in seguito, a quanto pare, il bacus era profondamente consapevole delle sue debolezze e si rese conto che ha sviluppato la "lingua di fondo-neimanovsky" da tutte le lingue di alto livello. Pertanto, il Pathos principale della sua critica era rivolto principalmente ai metodi di programmazione imperfetti.

Dal momento di pronunciare il discorso di Bacus nella programmazione, si sono verificati turni evidenti, sono apparse tecnologie funzionali e orientate agli oggetti, e con il loro aiuto riuscito a superare ciò che il bacus chiamava la "intelligente sfondo-nimanovsky bottiglia gola". Tuttavia, la causa principale della radice architettonica di questo fenomeno, la malattia congenita del canale tra memoria e processore - il suo throughput limitato - non è scomparso, nonostante i progressi nel campo della tecnologia negli ultimi 30 anni. Nel corso degli anni, questo problema è costantemente aggravato, poiché la velocità della memoria sta crescendo molto più lenta rispetto alle prestazioni dei processori, e il divario tra di loro sta diventando sempre di più.

Lo sfondo dell'architettura Nimanovsk del computer non è l'unico possibile. Dal punto di vista dell'organizzazione dei comandi di scambio tra il processore e la memoria, tutti i computer possono essere suddivisi in quattro classi:

  • SISD (singoli istruzioni singoli dati) - "Un flusso di comandi, un flusso di dati" ";
  • SIMD (singole istruzioni moltiplicare dati) - un flusso di comandi, molti flussi di dati;
  • Misd (Istruzioni multiple dati singoli) - Molti flussi di comando, un flusso di dati;
  • MIMD (più istruzioni multiple dati) - Molti flussi di comando, molti flussi di dati.

Da questa classificazione, si può vedere che la macchina Nimanovskaya è un caso speciale che cade nella categoria SISD. I possibili miglioramenti nell'ambito dell'architettura della SISD sono limitati ai trasportatori on-line e ad altri nodi funzionali aggiuntivi, nonché l'uso di diversi metodi di memorizzazione nella cache. Due altre categorie di architetture (SIMD, che includono processori vettoriali, e architetture MISD Trasportatore) sono state implementate in diversi progetti, ma non è diventato massiccio. Se rimani in questa classificazione, l'unica possibilità di superare le restrizioni della "gola della bottiglia" rimane lo sviluppo delle architetture della classe MIMD. Nel loro quadro, si trovano molti approcci: può essere varie architetture parallele e cluster e processori multi-filettati.

Pochi anni fa, a causa delle restrizioni tecnologiche, tutti i processori multi-thread sono stati costruiti sulla base di un nucleo, e tali multi-dimensioni sono state chiamate "simultanee" - Multithreading simultaneo (SMT). E con l'avvento dei processori multi-core, è apparso un tipo alternativo di multi-dimensionalità - Chip multiprocessori (CMP).

Caratteristiche dei processori multi-filettati

La transizione da semplici processori single-thread a un coniugato multi-flusso logicamente più complesso con difficoltà di superamento specifici, non ancora soddisfatte. Il funzionamento del dispositivo in cui il processo di esecuzione è diviso in agenti o filettature (thread) presenta due caratteristiche:

  • principio di non-determinazione (principio indeterminato). In un'applicazione multi-filettata, il processo è suddiviso in flussi interagibili senza certezza pre-concordata;
  • principio di incertezza. Il modo in cui le risorse saranno distribuite tra gli agenti di flussi sono anche sconosciuti in anticipo.

A causa di queste caratteristiche, il lavoro dei processori multi-thread è fondamentalmente diverso dai calcoli deterministici sullo schema Nimanov. In questo caso, lo stato attuale del processo non può essere definito come una funzione lineare dello stato precedente e ricevuto sull'input dei dati, sebbene ciascuno dei processi possa essere visualizzato come un micromano nimanan. (Nell'applicazione al comportamento dei flussi, è possibile utilizzare persino il termine "odity" utilizzato nella fisica quantistica.) La presenza di queste funzionalità porta il processore multi-thread alle idee su sistema complessoMa con un punto di vista puramente pratico, è chiaro che a livello di attuazione dei processi, nessuna non deterministica o incertezza, e ancor più riguardo alla stranezza e alla parola non può essere. Il programma correttamente eseguito non può essere strano.

Nella forma più generale, un processore multi-thread è costituito da due tipi di primitivi. Il primo tipo è una risorsa che supporta il flusso di un flusso, che si chiama Mutex (dalla reciproca esclusione - "Exception Exception") e il secondo evento. Il modo in cui è implementato fisicamente da uno o un altro mutex dipende dallo schema selezionato - SMT o CMP. In ogni caso, il processo è ridotto al fatto che il flusso successivo cattura il mutex durante la sua esecuzione, e quindi liberalo. Se Mutex è occupato in un unico flusso, il secondo flusso non può ottenerlo. La procedura specifica per il trasferimento di poteri al possesso di mutex da un flusso all'altro può essere casuale; Dipende dall'attuazione della gestione, ad esempio, in uno specifico sistema operativo. In ogni caso, è necessario costruire la gestione in modo che le risorse costituite da mutex siano distribuite correttamente e l'effetto di incertezza è stato soppresso.

Gli eventi sono oggetti (evento), segnalando la modifica dell'ambiente esterno. Possono tradursi in modalità standby prima di un altro evento o riportare le loro condizioni su un altro evento. In questo modo, gli eventi possono interagire tra loro, e la continuità dei dati tra gli eventi dovrebbe essere garantita. In attesa dell'esecuzione Un agente deve informare la disponibilità dei dati per questo. E come nella distribuzione del mutex, l'effetto dell'incertezza dovrebbe essere soppresso, quindi quando si lavora con gli eventi dovrebbe essere soppresso dall'effetto sconosciuto. Per la prima volta, lo schema SMT è stato implementato nei processori Compaq Alpha 21464, nonché in Intel Xeon MP e Itanium.

Logicamente CMP è più semplice: qui il parallelismo è assicurato dal fatto che ciascuno dei fili viene elaborato dal proprio nucleo. Ma se l'applicazione non può essere divisa in flussi, quindi (in assenza di misure speciali) viene elaborata da un nucleo, e in questo caso, le prestazioni generali del processore sono limitate alla velocità di un nucleo. A prima vista, il processore costruito secondo lo schema SMT è più flessibile, e quindi è preferibile questo schema. Ma tale affermazione è vera solo a bassa densità dei transistor. Se la frequenza è misurata da megaherter e il numero di transistor in un cristallo si avvicina a miliardi di miliardi, ei ritardi nei segnali di trasmissione diventano grandi del tempo di commutazione, i vantaggi ricevono la microarchitettura CMP in cui sono localizzati gli elementi di elaborazione associati.

Tuttavia, la parallelizzazione fisica porta al fatto che il CMP non è troppo efficace con i calcoli consecutivi. Per superare questo svantaggio, viene utilizzato l'approccio, chiamato "multi-dimensione speculativa" (multithreading speculativo). In russo, la parola "speculativa" ha una tonalità semantica negativa, quindi chiameremo tale multi-dimensionalità del "condizionale". Questo approccio suggerisce l'hardware o il supporto software per la fissione di una domanda seriale per flussi condizionali, corrispondendo alla loro implementazione e all'integrazione dei risultati in memoria.

EVOLUTION CMP.

I primi processori CMP di massa erano destinati al mercato del server. Indipendentemente dal venditore, loro, in sostanza, erano due processori supercalari indipendenti su un substrato. La principale motivazione della creazione di tali strutture è di ridurre il volume in modo che in una costruttive possa essere "imballaggio" più processori, aumentando la potenza specifica per volume dell'unità (che è fondamentale per i moderni data center). Quindi, a livello generale del sistema, alcuni risparmi aggiuntivi raggiungono, poiché i processori su un cristallo utilizzano risorse del sistema generale, come le comunicazioni ad alta velocità. Tipicamente, c'è solo un'interfaccia di sistema comune tra i processori adiacenti ( fico. uno, b).

Gli apologeti per l'utilizzo dei processori CMP giustificano ulteriormente (oltre due) aumento del numero di nuclei da parte delle funzionalità del carico del server, che distingue questo tipo di computer da sistemi di calcolo incorporati o destinati ai massicci sistemi di elaborazione. Dal server è necessaria una grande prestazione generale, ma il ritardo nel sistema non è così critico. Esempio banale: l'utente può semplicemente notare un ritardo millisecondo nell'aspetto di una pagina Web aggiornata, ma reagire molto dolorosamente al sovraccarico del server, che può causare interruzioni nella manutenzione.

La specificità del carico fornisce processori CMP un altro vantaggio notevole. Diciamo che la sostituzione del processore dual-core dello stesso core, è possibile raddoppiare la frequenza dell'orologio alle stesse prestazioni. Allo stesso tempo, il tempo teoricamente, il tempo di elaborazione di una richiesta separata può aumentare il doppio, ma poiché la separazione fisica dei flussi riduce la restrizione della "gola della bottiglia" dell'architettura Nymananovsk, il ritardo totale sarà significativamente inferiore al doppio del doppio. A bassa frequenza e complessità di un nucleo, il consumo di energia è significativamente ridotto, e con un numero crescente di nuclei, gli argomenti elencati a favore di CMP sono solo migliorati. Pertanto, il prossimo passo logicamente assolto è quello di raccogliere diversi nuclei e combinarli con una memoria di cache comune, ad esempio, come nel progetto Hydra (Figura 1, B). E poi puoi complicare il kernel e renderli multi-filettati, che è stato implementato nel progetto Niagara (figura 1, D).

La complessità dei processori ha un'altra manifestazione importante. La progettazione della numerazione dei prodotti miliardi di componenti sta diventando un compito sempre più laborioso - nonostante l'uso di strumenti di automazione. È significativo che stiamo assistendo più di un decennio "portare in mente" l'architettura IA-64. La progettazione del processore CMP è sostanzialmente più semplice: se c'è un kernel sviluppato, può essere replicato nelle quantità necessarie e il design è limitato dalla creazione dell'infrastruttura di cristallo interna. Inoltre, la semplicità dei nuclei semplifica il design plastoni di sistema.che si riduce al ridimensionamento, e in definitiva, gli indicatori dei sottosistemi I / O sono cambiati.

Nonostante gli argomenti di cui sopra, non vi sono motivi ragionevoli per una dichiarazione inequivocabile sui benefici del CMP rispetto a SMT. L'esperienza di creare processori L'attuazione di SMT è molto di più: dalla metà degli anni '80 sono state create diverse dozzine di prodotti sperimentali e diversi processori seriali. La storia dello sviluppo del CPM è ancora breve: se non tiene conto della famiglia di processori di segnalazione specializzati TMS 320C8X, il primo progetto di successo è diventato Hydra, realizzato in Standford University. Tra i progetti di ricerca universitaria rivolti a costruire processori CMP sono anche noti altri tre - Wisconsin MultiCalar, Carnegie-Mellon Stampede e MIT M-Machine.

Microprocessore Hydra.

Il cristallo Hydra è composto da quattro nuclei del processore basati su MIPS RISC-Architecture. Ogni kernel ha una cache di comando e una cache dei dati, e tutti i kernel sono combinati in una seconda cache di secondo livello. I processori eseguono un normale set di comandi MIPS più comandi di archiviazione condizionali (Store Conditional o SC), progettato per implementare primitivi di sincronizzazione. I processori e la memoria della cache di secondo livello sono combinati con pneumatici di lettura / scrittura e, inoltre, ci sono indirizzi ausiliari e pneumatici di controllo. Tutti questi pneumatici sono virtuali, cioè logicamente rappresentati da pneumatici cablati e sono fisicamente suddivisi in una pluralità di segmenti utilizzando ripetitori e buffer, il che consente di aumentare la velocità dei nuclei.

Il pneumatico Lettura / record svolge il ruolo del sistema. A causa della sua posizione all'interno del cristallo, ha sufficiente portata Per fornire scambio con cache per un ciclo. Raggiungere tali indicatori di performance di prestazioni anche nelle più costose architetture multiprocessore tradizionali difficili a causa delle restrizioni fisiche sul numero contatti esterni Processori. Efficace bus di scambio con memoria della cache impedisce il problema dell'emergere della "gola della bottiglia" tra nuclei e memoria.

I test dell'idra con carichi con parallelismo espressamente pronunciato sulle tipiche applicazioni Web e server hanno mostrato che le prestazioni dei quattro core rispetto a un nucleo aumentano di 3-3,8 volte, praticamente lineare. Ciò dà ragione di ritenere che i processori di questo tipo abbiano abbastanza "adattano" in quelle applicazioni in cui vengono utilizzati i server con l'architettura SMP. Ma è chiaro che il processore dovrebbe funzionare in modo abbastanza efficace con applicazioni coerenti, quindi uno dei compiti più importanti è implementare la multidimensizia condizionale. In Hydra, è attuato a livello hardware e la scelta di questo approccio è giustificata dal fatto che non richiede costi aggiuntivi per la programmazione delle applicazioni parallele.

La multi-dimensione condizionale si basa sulla partizione della sequenza di comando del programma sui flussi che possono essere eseguiti in parallelo. Naturalmente, potrebbe esserci interdipendenza logica tra tali flussi e lo speciale meccanismo di sincronizzazione è incorporato nel loro processore. L'essenza del suo lavoro è ridotta al fatto che se un po 'di thread richiede dati da un flusso parallelo, e non sono ancora pronti, quindi l'esecuzione di tale flusso è sospesa. In effetti, ci sono elementi di non determinazione, che è stato discusso sopra. Il processo di sincronizzazione è abbastanza complicato perché è necessario determinare tutte le possibili dipendenze tra i fili e le condizioni di sincronizzazione. La sincronizzazione condizionale consente di parallelare i programmi senza la conoscenza preliminare delle loro proprietà. È importante che il meccanismo di sincronizzazione sia dinamico, funziona senza l'intervento di un programmatore o compilatore, che è in grado solo per la divisione statica delle applicazioni ai flussi. I test del modello in base a diversi test hanno dimostrato che i mezzi di multi-dimensioni condizionali consentono di aumentare le prestazioni del processore più volte, e il parallelismo più ovvio è caratterizzato da un test, il valore inferiore tale è caratterizzato.

Nel 2000, Afara è stato creato nella situazione di stretta segretezza. I suoi fondatori divennero professor Kunle Olukotun da Stanford University e il noto sviluppatore di processori del processore Kon, che ha avuto esperienza in Intel e Sun Microsystems. Kon è stato uno degli autori dei processori I860 e I960 RISC nella prima di queste corporazioni e UltraSPARC-I nel secondo. Sotto la sua leadership, Hydra è stata riciclata sotto i core del processore in base al processore SPARC. Nel 2002, Afara è stato acquistato da Sun Microsystems, e questo ha concluso la storia del progetto Hydra e la storia del Niagara è iniziata.

Niagara - "lega" Majc e Hydra

Al processore UltraSPARC T1, più noto come Niagara, due predecessori principali - Hydra e Majc.

A metà degli anni '90, su un'ondata di hobby, processori Java specializzati, il Sun Microsystems ha tentato di creare un processore "con una parola molto lunga" - parola di istruzioni molto lunga (VLiW). Questa iniziativa è stata nominata Majc (architettura a microprocessore per Java Computing). Come in altri progetti iniziati in quel momento (Intel IA-64 Itanium), in questo caso c'era un compito di trasferire alcune delle operazioni più difficili per mantenere il compilatore. La logica del transistor rilasciata può essere utilizzata per creare nodi funzionali più produttivi (unità funzionali) per fornire scambio produttivo di comandi e dati tra le CPU, la memoria della cache e la memoria di base. Così, lo sfondo-nimanovsky "bottiglia gola" è stato superato.

La Majc era diversa dalla maggior parte dei processori in assenza di coprocessori specializzati (sottocrogatori), che sono comunemente chiamati dispositivi funzionali destinati ad eseguire operazioni con numeri interi, numeri di punti flottanti e dati multimediali. In tutto dispositivi funzionali erano gli stessi in grado di eseguire qualsiasi operazione, che, da un lato, ridotta l'efficacia delle singole operazioni, ma sull'altro sollevato il tasso di utilizzo dell'intero processore.

Niagara incarna il meglio di due approcci alternativi all'attuazione di multi-dimensioni - SMT e CMP. A prima vista, è molto simile a Hydra, ma piuttosto Hydra può essere chiamato "Layout" Niagara. Oltre al fatto che in quest'ultimo - il doppio dei due nuclei, ognuno di loro può elaborare quattro flussi.

Il processore Niagara fornisce supporto hardware per l'esecuzione di 32 thread diviso in otto gruppi (quattro fili ciascuno). Per eseguire ciascun gruppo, serve il suo canale di elaborazione della pipeline SPARC ( fig.2.). È un core del processore, costruito in conformità con l'architettura dello SPARC V9. Ogni pipeline SPARC contiene una cache di primo livello per comandi e dati. Insieme, 32 flussi utilizzano una memoria della cache di secondo livello con una capacità di 3 Mb, divisa in quattro banche. L'interruttore collega otto nuclei, banche di cache di secondo livello e altre risorse della CPU distribuita e supporta il tasso di cambio di 200 GB / s. Inoltre, lo switch contiene una porta per sistemi I / O e canali a memoria DDR2 DRAM, fornendo il tasso di cambio di 20 GB / s; La capacità massima della memoria è fino a 128 GB.

Il progetto Niagara è focalizzato sul sistema operativo Solaris, quindi tutte le applicazioni che eseguono Solaris possono essere eseguite su un nuovo processore senza alcuna modifica. Il software applicativo percepisce il Niagara come 32 processori discreti.

Progetto cellulare

Il proprio approccio alla creazione di processori multi-core è stata offerta IBM Corporation, il cui progetto cellulare è stato nominato "Multiprocessore di chip eterogeneo). L'architettura cellulare si riferisce anche all'architettura del motore a banda larga cellulare (CBEA). Il multiprocessore cellulare è costituito dal kernel di architettura di energia IBM 64-bit e otto coprocessori specializzati che implementano il programma "un comando un sacco di dati". In IBM, questa architettura è chiamata unità di processore sinergica (SPU). Può essere utilizzato con successo se necessario per elaborare i flussi di dati di grandi dimensioni, ad esempio nella crittografia, in diverse applicazioni multimediali e scientifiche, come la velocità di trasformazione di Fourier o Matrix veloce. L'architettura cellulare è stata creata dai ricercatori di ricerca IBM in collaborazione con colleghi di IBM Systems Technology Group, Sony e Toshiba, e la sua prima applicazione dovrebbe essere dispositivi multimediali che richiedono grandi quantità di calcoli.

La base dell'unità del processore sinergica è un insieme di architettura set di istruzioni (ISA). I comandi hanno una lunghezza di 32 bit e sono indirizzati a tre operandi inseriti nel pool di registro, che consiste di registri a 128 bit in ciascuna.

In futuro, l'uso della cellula non sarà limitato sistemi di gioco. Sulla coda - Televisione alta definizione, I server domestici e persino i supercomputer.

Letteratura
  1. Leonid Chernyak. L'audit del primato - la fine della stagnazione? // sistemi aperti. - 2003, №5.
  2. Mikhail Kuzminsky. Architettura a microprocessore multilinea // sistemi aperti. - 2002, №1.
  3. Rajat a Dua, Bhushan Lokhande. Uno studio comparativo dei multiprocessori SMT e CMP. -

Avendo capito con la teoria del multithreading, considera l'esempio pratico - Pentium 4. Già nella fase di sviluppo di questo processore, Intel Engineers ha continuato a lavorare sul miglioramento delle sue prestazioni senza apportare modifiche all'interfaccia del programma. I cinque modi semplici sono stati considerati:
1. Aumentare la frequenza dell'orologio.
2. Posizionamento su un chip di due processori.
3. Introduzione di nuovi blocchi funzionali.
1. Estensione del trasportatore.
2. Utilizzo di multithreading.
Il modo più ovvio per migliorare la velocità è aumentare la frequenza dell'orologio senza modificare altri parametri. Di norma, ogni modello del processore successivo ha una frequenza di clock leggermente superiore rispetto a quella precedente. Sfortunatamente, con un semplice aumento della frequenza dell'orologio, gli sviluppatori devono affrontare due problemi: un aumento del consumo energetico (che è rilevante per computer portatili e altri dispositivi di calcolo che eseguono batterie) e surriscaldamento (che richiede la creazione di dissipatori di calore più efficienti).
Il secondo metodo è il posizionamento sul chip di due processori - relativamente semplice, ma è associato al raddoppio dell'area occupata dal microcircuito. Se ogni processore viene fornito con la propria memoria della cache, il numero di microcircuiti sulla piastra è a fissaggio, ma significa anche raddoppiare il costo della produzione. Se per entrambi i processori c'è una memoria della cache comune, è possibile evitare un aumento significativo dell'area occupata, ma in questo caso si verifica un altro problema - la quantità di memoria della cache in termini di ciascun processore è dimezzata, e questo è inevitabilmente influenzato dalle prestazioni . Inoltre, se le applicazioni del server professionale sono in grado di utilizzare completamente le risorse di diversi processori, nei programmi desktop convenzionali il parallelismo interno è sviluppato in misura molto minore.
Anche l'introduzione di nuovi blocchi funzionali non è difficile, ma è importante mantenere l'equilibrio. Qual è il significato dei primi dieci blocchi di ALU, se il chip non può emettere comandi al trasportatore ad una velocità che consente di scaricare tutti questi blocchi?
Il trasportatore con un aumento del numero di passaggi in grado di separare i compiti in segmenti più piccoli ed elaborarli in brevi periodi di tempo, da un lato, aumenta le prestazioni, dall'altro, migliora le conseguenze negative di previsione errata delle transizioni, dei cacciatori, degli interrupt e altri eventi che violano i normali comandi di elaborazione del corso nel processore. Inoltre, per attuare pienamente le possibilità di un trasportatore espanso, è necessario aumentare la frequenza dell'orologio, e questo, come sappiamo, porta ad un aumento del consumo di energia e del trasferimento di calore.
Infine, è possibile implementare il multithreading. Il vantaggio di questa tecnologia è quello di introdurre un flusso software aggiuntivo che consente di entrare in vigore quelle risorse hardware che altrimenti sarebbero state semplici. Secondo i risultati degli studi sperimentali, gli sviluppatori Intel hanno scoperto che l'aumento dell'area del microcircuito del 5% nell'attuazione del multithreading per molte applicazioni fornisce un aumento del 25%. Xeon 2002 è diventato il primo processore Intel con il supporto per il multithreading. Successivamente, a partire dalla frequenza di 3,06 GHz, il multithreading è stato introdotto nel Pentium 4. Intel Ruliere chiama l'implementazione di multithreading in Pentium 4 ipermacato (iperthreading).
Il principio principale dell'iperpotitimità è l'esecuzione simultanea di due flussi software (o processi - il processore non distingue i processi dai flussi software). Il sistema operativo considera il processore di ipervisioni Pentium 4 come complesso a due processori con cache comuni e memoria di base. Pianificazione del sistema operativo esegue per ciascun flusso software separatamente. Pertanto, due applicazioni possono essere eseguite allo stesso tempo. Ad esempio, il programma di posta può inviare o ricevere messaggi a modalità di sfondoFino a quando l'utente non interagisce con l'applicazione interattiva, cioè, il DAEMON e il programma utente vengono eseguiti simultaneamente, come se due processori sono disponibili per il sistema.
I programmi di applicazione che coinvolgono la possibilità di esecuzione nella forma di diversi flussi software possono utilizzare sia i "processori virtuali". Ad esempio, i programmi di editing video di solito consentono agli utenti di applicare i filtri a tutti i frame. Tali filtri regolano la luminosità, il contrasto, il bilanciamento del colore e altre proprietà dei fotogrammi. In tale situazione, il programma può assegnare un processore virtuale di elaborare anche i telai e l'altro per elaborare dispari. Allo stesso tempo, due processori funzioneranno completamente indipendentemente l'uno dall'altro.
Poiché i flussi software si rivolgono alle stesse risorse hardware, è necessario il coordinamento del filo. Nel contesto dell'ipertensione, gli sviluppatori Intel hanno identificato quattro utili strategie di gestione della gestione delle risorse: duplicazione delle risorse, nonché rigide, soglia e separazione delle risorse complete. Considera queste strategie.
Iniziamo con la duplicazione delle risorse (duplicazione delle risorse). Come sapete, alcune risorse vengono duplicate allo scopo di organizzare i flussi software. Ad esempio, poiché ogni flusso software richiede il controllo individuale, è necessario un secondo contatore di comando. Inoltre, è necessario inserire la seconda tabella di visualizzazione dei registri architettonici (EAH, UE, ecc.) Ai registri fisici; Allo stesso modo, il controller di interrupt è duplicato, poiché l'elaborazione degli interrupt per ciascun flusso viene eseguita individualmente.
Successivamente, il metodo di condivisione delle risorse partizionato è seguito tra flussi software. Ad esempio, se il processore fornisce una coda tra le due fasi funzionali del trasportatore, la metà delle fessure può essere data un flusso 1, l'altra metà-flusso 2. La separazione delle risorse è facilmente implementata, non porta al Squilibrio e fornisce completa indipendenza dei flussi software l'uno dall'altro. Con la piena divisione di tutte le risorse, un processore è effettivamente trasformato in due. D'altra parte, potrebbe esserci una tale situazione in cui un thread del programma non utilizza le risorse che potrebbero essere utili al secondo flusso, ma nel rispetto di cui non ha un'autorità di accesso. Di conseguenza, le risorse che in una situazione diversa potrebbero essere coinvolte sono inattive.
L'opposto della separazione rigida è una separazione completa delle risorse (condivisione delle risorse complete). In questo schema, qualsiasi Stream Software può accedere alle risorse desiderate e sono servite in ordine per le richieste di accesso. Considera una situazione in cui un flusso veloce costituito principalmente da addizione e le operazioni di sottrazione coesistono con un flusso lento che implementa le operazioni di moltiplicazione e divisione. Se i comandi vengono chiamati la memoria più velocemente rispetto alle operazioni di moltiplicazione e divisione vengono eseguite, il numero di comandi causati all'interno del quadro del flusso lento e della coda sul trasportatore crescerà gradualmente. In definitiva, questi comandi riempiranno la coda, di conseguenza, il flusso rapido dovuto alla mancanza di spazio si fermerà in esso. La separazione completa delle risorse risolve il problema della spesa non ottimale delle risorse condivise, ma crea uno squilibrio del loro consumo - un filo può rallentare o fermare l'altro.
Lo schema intermedio è implementato all'interno della soglia delle risorse (condivisione delle risorse di soglia). Secondo questo schema, qualsiasi streaming software può ricevere dinamicamente un certo volume di risorse (limitato). Per quanto riguarda le risorse replicate, questo approccio fornisce flessibilità senza una minaccia a uno dei flussi software a causa dell'impossibilità di ottenere risorse. Se, ad esempio, per proibire a ciascuno dei flussi di occupare più di 3/4 delle code dei comandi, l'aumento del consumo di risorse con un flusso lento non impedirà l'esecuzione del rapido.
Il modello Hyperplow Pentium 4 combina diverse strategie di separazione delle risorse. Pertanto, è fatto un tentativo per risolvere tutti i problemi associati a ciascuna strategia. La duplicazione è implementata per quanto riguarda le risorse, l'accesso a cui è costantemente richiesto da entrambi i flussi software (in particolare, in relazione al misuratore di comando, alle tabelle del display e ai controller di interruzione). La duplicazione di queste risorse aumenta l'area del microcircuito solo solo del 5% - è d'accordo, una commissione abbastanza ragionevole per il multithreading. Risorse disponibili in tale volume che è praticamente eliminata dalla probabilità di catturarli con un flusso (ad esempio, le righe della cache) sono distribuite dinamicamente. Accesso alle risorse che controllano il lavoro del trasportatore (in particolare, le sue numerose code) sono divise - la metà delle fessure viene data a ciascun programma. Il principale trasportatore dell'architettura NetBursst implementato in Pentium 4 è rappresentato in FIG. 8.7; Bianco I. aree grigie Questa illustrazione indica il meccanismo di allocazione delle risorse tra flussi software bianchi e grigi.
Come puoi vedere, tutte le code su questa illustrazione sono divise: ogni flusso software è evidenziato a metà delle slot. Nessuno dei flussi software può limitare il funzionamento di un altro. Anche l'unità di distribuzione e la sostituzione è separata. Le risorse del pianificatore sono divise dinamicamente, ma in base a un determinato valore di soglia - quindi, nessuno dei thread può prendere tutti i livelli della coda. Per tutte le altre fasi del trasportatore, c'è una separazione completa.
Tuttavia, con il multithreading non tutto è così semplice. Anche una tale tecnica progressiva ha le carenze. La separazione rigida delle risorse non è associata a costi gravi, ma la separazione dinamica, in particolare, tenendo conto delle soglie, richiede di monitorare il consumo di risorse nella fase di esecuzione. Inoltre, in alcuni casi, i programmi funzionano significativamente meglio senza multithreading che con esso. Supponiamo, ad esempio, in presenza di due flussi software per il normale funzionamento, ognuno di essi richiede 3/4 cache. Se sono stati eseguiti alternativamente, ognuno mostrerebbe sufficiente efficienza con una piccola quantità di missioni della cache (come noto essere correlato a costi aggiuntivi). Nel caso dell'esecuzione parallela dei mancamenti della cache, tutti sarebbero molto più grandi e il risultato finale sarebbe peggiore che senza multithreading.
Per ulteriori informazioni sul meccanismo di ripetizione multithreading 4, puoi imparare.

La campana.

Ci sono quelli che hanno letto questa notizia prima di te.
Iscriviti per ricevere articoli freschi.
E-mail
Nome
Cognome
Come vuoi leggere la campana
Senza spam.