Cosa fa il processore mentre attende il recupero della memoria principale


26

Supponendo che le richieste di cache l1 e l2 generino un errore, il processore si blocca fino a quando non si accede alla memoria principale?

Ho sentito dell'idea di passare a un altro thread, in caso affermativo cosa viene utilizzato per riattivare il thread bloccato?


4
Che ricerca hai fatto? Queste sono certamente informazioni disponibili. Lascerò rispondere agli esperti, ma non credo che un cambio di filo sia una cosa utile da fare. In genere, il cambio di contesto su una CPU indurrà molti accessi alla memoria (e, quindi, probabilmente mancati cache). Esistono alcune misure come il riordino delle operazioni (utilizzando la pipeline) ma lo stallo sembra non avere alternative.
Raffaello

@Raphael Ho letto principalmente libri di architettura informatica, l'architettura ARM System-on-Chip di Steve Furber, probabilmente il più completo che abbia letto completamente. Tuttavia, ho iniziato a leggere Computer Architecture: A Quantitative Approach. Discute le tecniche per evitare lo stallo come il cambio di thread, OOE e le operazioni di memoria fuori servizio, anche se non dà mai molto riguardo alle complessità dei design moderni, come la maggior parte dei libri di testo coprono architetture più vecchie o danno vaghi suggerimenti su come siano queste cose implementato e lavorare insieme.
102948239408,

Espandendo la mia domanda, le cache sembrano avere latenze minime ed essere deterministiche nella loro risposta, ma nel caso in cui una tabella di scenari di scenario peggiori passi per recuperare l'indirizzo fisico, potrebbero essere completate migliaia di istruzioni, alcune provenienti dallo stesso thread estratto da ILP. Quali interazioni hardware si verificano sul processore per decidere che può pianificare un altro thread e quale comunicazione viene utilizzata per riattivare quel thread se ciò accade. Inoltre, se OoOE esiste una tecnica per gestire una coda di risultati completa quando si cambia thread?
102948239408,

1
Non è chiaro dalla tua domanda che sei interessato ai dettagli delle CPU moderne. Non solo è probabilmente offtopico, ma potrebbe anche essere informazioni proprietarie. Con i concetti, possiamo aiutarti; questi probabilmente sono cambiati meno nel corso dei decenni rispetto alle implementazioni. Per quanto riguarda la tua domanda, ti preghiamo di inserire ciò che conosci e formulare una domanda specifica, concettuale (o di richiesta di riferimento).
Raffaello

1
Ho risposto ai concetti generali, ma a giudicare dai tuoi commenti, potresti essere dopo considerazioni più avanzate. Tuttavia, se desideri risposte più avanzate, dovrai rendere la tua domanda più specifica per particolari architetture e tipi di tecniche.
Gilles 'SO- smetti di essere malvagio' il

Risposte:


28

La latenza della memoria è uno dei problemi fondamentali studiati nella ricerca sull'architettura informatica.

Esecuzione speculativa

L'esecuzione speculativa con problema di istruzioni fuori servizio è spesso in grado di trovare lavoro utile da fare per colmare la latenza durante un hit della cache L1, ma di solito si esaurisce il lavoro utile dopo circa 10 o 20 cicli o giù di lì. Ci sono stati diversi tentativi per aumentare la quantità di lavoro che può essere fatto durante una mancanza a lunga latenza. Un'idea era quella di provare a fare previsioni di valore (Lipasti, Wilkerson e Shen, (ASPLOS-VII): 138-147, 1996). Questa idea è stata molto di moda nei circoli di ricerca dell'architettura accademica per un po 'ma sembra non funzionare nella pratica. Un ultimo tentativo per salvare la previsione del valore dalla pattumiera della storia è stata l'esecuzione di runahead(Mutlu, Stark, Wilkerson e Patt (HPCA-9): 129, 2003). Nell'esecuzione di runahead riconosci che le tue previsioni di valore saranno sbagliate, ma esegui comunque speculativamente e poi butta via tutto il lavoro basato sulla previsione, sulla teoria che almeno avvierai alcuni prefetch per quella che altrimenti sarebbe cache L2 manca. Si scopre che Runahead spreca così tanta energia da non valerne la pena.

Un approccio finale in questo senso che potrebbe avere una certa forza nell'industria comporta la creazione di buffer di riordino estremamente lunghi. Le istruzioni vengono eseguite in modo speculativo in base alla previsione del ramo, ma non viene eseguita alcuna previsione del valore. Invece tutte le istruzioni che dipendono da un carico a lunga latenza mancano di sit sit e attendono nel buffer di riordino. Ma poiché il buffer di riordino è così grande, puoi continuare a recuperare le istruzioni se il predittore di rami sta facendo un lavoro decente, a volte sarai in grado di trovare lavoro utile molto più tardi nel flusso di istruzioni. Un documento di ricerca influente in questo settore è stato il gasdotto a flusso continuo(Srinivasan, Rajwar, Akkary, Gandhi e Upton (ASPLOS-XI): 107-119, 2004). (Nonostante il fatto che gli autori provengano tutti da Intel, credo che l'idea abbia avuto maggiore trazione su AMD.)

Multi-threading

L'uso di più thread per la tolleranza di latenza ha una storia molto più lunga, con un successo molto maggiore nel settore. Tutte le versioni di successo utilizzano il supporto hardware per il multithreading. La versione più semplice (e di maggior successo) di questo è quella che viene spesso chiamata FGMT ( multi-threading a grana fine ) o multi-threading interfogliato . Ogni core hardware supporta più contesti di thread (un contesto è essenzialmente lo stato del registro, inclusi i registri come il puntatore dell'istruzione e tutti i registri dei flag impliciti). In un processore multi-threading grana fine ogni filo viene elaborato in-ordine. Il processore tiene traccia di quali thread sono bloccati in caso di mancanza di carico a lunga latenza e quali sono pronti per le loro istruzioni successive e utilizza una semplice strategia di pianificazione FIFO su ciascun ciclo per scegliere quale thread pronto eseguire quel ciclo. Un primo esempio di questo su larga scala furono i processori HEP di Burton Smith (Burton Smith progettò il supercomputer Tera, che era anche un processore multi-threading a grana fine). Ma l'idea va molto più indietro, negli anni '60, credo.

FGMT è particolarmente efficace sui carichi di lavoro in streaming. Tutte le moderne GPU (unità di elaborazione grafica) sono multicore in cui ogni core è FGMT e il concetto è ampiamente utilizzato anche in altri domini di elaborazione. Il T1 di Sun era anche FMGT multicore, così come lo è Xeon Phi di Intel (il processore che spesso viene ancora chiamato "MIC" e un tempo si chiamava "Larabee").

L'idea del Multithreading simultaneo (Tullsen, Eggers e Levy, (ISCA-22): 392-403, 1995) combina il multi-threading hardware con l'esecuzione speculativa. Il processore ha più contesti di thread, ma ogni thread viene eseguito in modo speculativo e fuori servizio. Uno scheduler più sofisticato può quindi utilizzare varie euristiche per recuperare dal thread che ha più probabilità di avere un lavoro utile ( Malik, Agarwal, Dhar e Frank, (HPCA-14: 50-61), 2008 ). Una certa grande azienda di semiconduttori ha iniziato a usare il termine hyperthreading per il multithreading simultaneo, e quel nome sembra essere quello più utilizzato in questi giorni.

Preoccupazioni microarchitetturali di basso livello

Mi sono reso conto dopo aver riletto i tuoi commenti che sei interessato anche alla segnalazione che passa tra processore e memoria. Le cache moderne di solito consentono a più missioni di essere contemporaneamente eccezionali. Questa è chiamata cache senza Lockup (Kroft, (ISCA-8): 81-87, 1981). (Ma il documento è difficile da trovare online e un po 'difficile da leggere. Risposta breve: c'è un sacco di contabilità ma ci si occupa solo di esso. La struttura di contabilità hardware si chiama MSHR (informazioni mancanti / registro di conservazione dello stato ), che è il nome che Kroft gli ha dato nel suo articolo del 1981).


Grazie risposta davvero completa, proverò a esaminare la cache senza blocco. La mia domanda mal formulata stava davvero cercando di confermare che i processori continuavano con carichi e archivi durante un accesso alla memoria principale e quali tecniche microarchitetturali sono state usate per farlo.
102948239408,

+1, 1. È davvero l'elaborazione a botte se non si utilizza la pianificazione round robin? Wikipedia lo rende sinonimo di FGMT. (Posso accettare l'applicazione del "processore a botte" al round robin con i salti, sebbene ciò rompa l'analogia in quanto un pentagramma mancante (cfr. Thread non pronto) non contrae la circonferenza di un barile. (Penso che i "veri" processori a botte fossero raro - forse il processore periferico per il CDC 6600? - perché sprecano un ciclo ma semplifica l'hardware.) 2. Una menzione di SoEMT come Hyper-Threading di Itanium e Northstar et al. di IBM sembra particolarmente appropriata data la domanda.
Paul A. Clayton,

@ 102948239408, un'altra cosa per cui potresti cercare su Google sono termini come "hit under miss" e "miss under miss" (l'altra opzione è "stall under miss", ma l'ho appena provato e sembra non restituire nulla di utile.) termini attualmente utilizzati da (alcuni) architetti per diverse opzioni di ciò che la cache potrebbe consentire.
Wandering Logic,

@ PaulA.Clayton, la terminologia non è sicuramente il mio punto di forza. Sono d'accordo con te sul fatto che l'elaborazione a botte dovrebbe significare round-robin. Ma non riesco a pensare a nessun altro termine che significhi: interleaving ciclo per ciclo di un mucchio di thread in ordine (che è ciò che fanno GPU, Xeon Phi e Sun T1). È FGMT? Ho sempre pensato a FGMT come a includere SMT, (cioè, non specifica che i thread debbano essere eseguiti in ordine) ma forse FGMT è meglio di "processore a botte" in questo caso?
Wandering Logic,

L'articolo del processore Barrel di Wikipedia afferma: "noto anche come" multithreading temporale "" a foglia singola "o" a grana fine ", quindi IMT e FGMT sono termini almeno riconosciuti. Penso di aver letto "a grana fine" più di "interleaved", ma interleaved non è raro. In genere ho usato FG (per me "granuloso" implica più separazione di quella fornita da SMT); FG ha il vantaggio che interleaved potrebbe applicare a SoEMT. Ho il sospetto che questo sia solo un cambiamento nell'uso del "processore a botte" che dovrò sorridere (d i denti) e sopportare.
Paul A. Clayton,

16

La risposta breve è: niente, il processore si blocca.

Non ci sono così tante possibilità. Passare a un'attività diversa non è in realtà un'opzione per due motivi. È un'operazione costosa e poiché l'attività corrente e l'altra attività sono in competizione per lo spazio nella cache, il passaggio all'altra attività potrebbe richiedere un accesso alla memoria principale e quindi tornare all'attività originale. Inoltre, ciò dovrebbe coinvolgere il sistema operativo, quindi il processore dovrebbe innescare una qualche forma di interruzione o trappola - in effetti il ​​processore passerebbe a un po 'di codice del kernel.

Mentre il processore è in stallo, il timer continua a funzionare, quindi potrebbe esserci un interruzione del timer o potrebbe esserci un interruzione da altre periferiche. Quindi è più probabile che si verifichi un cambio di contesto durante l'accesso alla memoria principale rispetto a un accesso alla cache, ma solo perché richiede più tempo.

Tuttavia i computer moderni includono una varietà di tecniche per cercare di ridurre il tempo sprecato nel processore in attesa della memoria principale. Lo stallo si verifica, ma solo quando non può essere evitato.

Una tecnica è il recupero speculativo : il processore tenta di indovinare a quale posizione della memoria si accederà e la recupera in cache in anticipo. Ad esempio, i loop su un blocco di memoria sono comuni, quindi se le linee della cache sono state caricate per gli indirizzi di memoria 0x12340000, 0x12340010 e 0x12340020, potrebbe essere una buona idea caricare la riga per 0x12340030. Il compilatore può essere utile generando istruzioni di prefetch che sono come carichi, tranne per il fatto che trasferiscono solo i dati dalla memoria principale alla cache, non in un registro del processore.

Un'altra tecnica è l' esecuzione speculativa . Il processore inizia a eseguire l'istruzione successiva prima dell'esecuzione del caricamento. Ciò accade naturalmente a causa della pipeline delle istruzioni. Solo le istruzioni che non dipendono dal valore caricato possono essere eseguite in questo modo: il processore deve eseguire un'analisi delle dipendenze. Per istruzioni condizionali (ad es. Caricamento r1; ramo se r1 ≠ 0), i processori impiegano l' euristica di previsione del ramo per indovinare quale sarà il valore. Potrebbe essere necessario riavvolgere l'esecuzione speculativa dopo un carico nel caso in cui il carico inneschi un'interruzione.

Alcune architetture come Itanium facilitano l'esecuzione delle istruzioni in un comodo ordine consentendo il riordino delle istruzioni di default: invece di consistere in una sequenza di istruzioni elementari che vengono eseguite semanticamente una dopo l'altra, i programmi sono composti da parole di istruzioni molto lunghe : una singola istruzione include molte operazioni che devono essere eseguite in parallelo da diversi componenti del processore.

Il passaggio a un altro thread avviene nell'hyperthreading , presente nei processori x86 di fascia alta. Questa è una tecnica di progettazione hardware: ogni core del processore contiene due banchi di registro separati (ciascuno corrispondente a un contesto di attività), ma una singola istanza di altri elementi, in modo che possa supportare due thread di esecuzione indipendenti, ma eseguire efficacemente solo le istruzioni da uno a un tempo. Mentre un thread è in stallo, l'altro thread procede. Dal punto di vista del software, ci sono due processori indipendenti; succede solo che quei processori condividono molti componenti sotto il cofano.

Lo scambio è di un altro livello nella gerarchia della cache di memoria: la memoria principale può essere vista come una cache per lo spazio di swap. Con lo scambio, i meccanismi e i rapporti di prestazione sono diversi. Se un'attività richiede che i dati vengano caricati da swap, l'istruzione load attiva una trap che esegue il codice del kernel per allocare una pagina nella RAM e caricarne il contenuto dal disco. Mentre ciò accade, il kernel potrebbe decidere di passare a un'altra attività.


Contrariamente al primo e al penultimo paragrafo, il "trucco" è che non deve avvenire un cambio di contesto reale con l'hyperthreading, giusto? La CPU mantiene completamente due contesti contemporaneamente.
Raffaello

1
@Raphael Right: per quanto riguarda il software, per tutto tranne che per le prestazioni, ci sono due CPU.
Gilles 'SO- smetti di essere malvagio' il

Una CPU hyperthreaded ha molte unità di esecuzione semi-indipendenti (numeri interi e in virgola mobile, moltiplicatori, ecc.), E penso che entrambi i contesti possano usare contemporaneamente unità di esecuzione separate, ma non sono sicuro al 100% di questo.
Russell Borogove,

@RussellBorogove Sì, non ho menzionato, perché anche le CPU non hyperthreaded può avere più ALU / FPU / ... e viceversa nuclei separati a volte condividono FPU, ecc
Gilles 'SO-tappa è male'

5

La risposta a questa domanda varierà con l'architettura in questione. Mentre molte CPU si fermeranno (ARM, x86 senza hyperthreading, ecc.) Perché impiegano troppo tempo a cambiare thread, questo non è l'approccio adottato da ogni architettura. In alcune architetture, ogni thread pianificato su una CPU ha il proprio file di registro indipendente, quindi il processore può semplicemente eseguire il lavoro da un thread che non è in attesa di un accesso alla memoria. Comprendo che questo è, in misura limitata, ciò che fa l'hyperthreading x86 (usando solo 2 thread), ma è molto più comune su GPGPUarchitetture. Nel caso particolare di CUDA, almeno dozzine, se non centinaia, di orditi di fili vengono solitamente caricati su un dato multiprocessore in un dato momento, con ogni filo (centinaia o migliaia di essi) con i propri registri. Ciò consente all'architettura di eseguire un'istruzione da un altro thread nel ciclo successivo quando un determinato thread emette un accesso alla memoria. Pertanto, finché vengono caricati abbastanza thread, i core del processore non sono mai inattivi per gli accessi alla memoria. Vedere le Linee guida sulle prestazioni e la gerarchia della memoria per ulteriori informazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.