L' articolo di Wikipedia su EPIC ha già delineato i molti pericoli comuni a VLIW ed EPIC.
Se qualcuno non cattura il senso di fatalismo da quell'articolo, vorrei evidenziarlo:
Le risposte di caricamento da una gerarchia di memoria che include cache della CPU e DRAM non hanno un ritardo deterministico.
In altre parole, qualsiasi progetto hardware che non riesce a far fronte (*) alla latenza non deterministica dall'accesso alla memoria diventerà semplicemente un fallimento spettacolare.
(*) "Affrontando", è necessario ottenere prestazioni di esecuzione ragionevolmente buone (in altre parole "competitive in termini di costi"), il che richiede di non lasciare la CPU inattiva per decine o centinaia di cicli così spesso.
Si noti che la strategia di coping adottata da EPIC (menzionata nell'articolo Wikipedia collegato sopra) non risolve effettivamente il problema. Dice semplicemente che l'onere di indicare la dipendenza dei dati ora ricade sul compilatore. Va bene; il compilatore dispone già di tali informazioni, quindi è semplice che il compilatore si conformi. Il problema è che la CPU resterà inattiva per decine o centinaia di cicli su un accesso alla memoria. In altre parole, esternalizza una responsabilità secondaria, pur non riuscendo a far fronte alla responsabilità primaria.
La domanda può essere riformulata come: "Data una piattaforma hardware destinata a fallire, perché (1) non (2) gli autori del compilatore non hanno potuto fare uno sforzo eroico per riscattarla?"
Spero che la mia riformulazione renderà ovvia la risposta a questa domanda.
C'è un secondo aspetto del fallimento che è anche fatale.
Le strategie di coping (menzionate nello stesso articolo) presuppongono che il prefetching basato su software possa essere utilizzato per recuperare almeno parte della perdita di prestazioni dovuta alla latenza non deterministica dall'accesso alla memoria.
In realtà, il prefetching è redditizio solo se si eseguono operazioni di streaming (lettura della memoria in modo sequenziale o altamente prevedibile).
(Detto questo, se il tuo codice accede frequentemente ad alcune aree di memoria localizzate, la memorizzazione nella cache ti aiuterà.)
Tuttavia, la maggior parte dei software per scopi generici deve effettuare numerosi accessi casuali alla memoria. Se consideriamo i seguenti passaggi:
- Calcola l'indirizzo e quindi
- Leggi il valore e quindi
- Usalo in alcuni calcoli
Per la maggior parte dei software generici, questi tre devono essere eseguiti in rapida successione. In altre parole, non è sempre possibile (entro i limiti della logica del software) calcolare l'indirizzo in anticipo o trovare abbastanza lavoro da fare per riempire le bancarelle tra questi tre passaggi.
Per aiutare a spiegare perché non è sempre possibile trovare abbastanza lavoro per riempire le bancarelle, ecco come è possibile visualizzarlo.
- Diciamo, per nascondere efficacemente le bancarelle, dobbiamo riempire 100 istruzioni che non dipendono dalla memoria (quindi non soffriranno di ulteriore latenza).
- Ora, come programmatore, caricare qualsiasi software di propria scelta in un disassemblatore. Scegli una funzione casuale per l'analisi.
- Riesci a identificare ovunque una sequenza di 100 istruzioni (*) che sono esclusivamente prive di accessi di memoria?
(*) Se potessimo mai NOP
fare un lavoro utile ...
Le moderne CPU cercano di far fronte alle stesse informazioni dinamiche, monitorando contemporaneamente l'avanzamento di ciascuna istruzione mentre circolano attraverso le condutture. Come ho accennato in precedenza, parte di tali informazioni dinamiche è dovuta a una latenza di memoria non deterministica, pertanto non può essere prevista con precisione da alcun compilatore. In generale, al momento della compilazione non sono disponibili informazioni sufficienti per prendere decisioni che potrebbero riempire quelle bancarelle.
In risposta alla risposta di AProgrammer
Non è che "compilatore ... estrarre il parallelismo è difficile".
Il riordino della memoria e delle istruzioni aritmetiche da parte dei moderni compilatori è la prova che non ha problemi a identificare operazioni indipendenti e quindi eseguibili contemporaneamente.
Il problema principale è che la latenza di memoria non deterministica significa che qualsiasi "accoppiamento di istruzioni" codificato per il processore VLIW / EPIC finirà per essere bloccato dall'accesso alla memoria.
L'ottimizzazione delle istruzioni che non si bloccano (solo registro, aritmetica) non aiuterà con i problemi di prestazioni causati da istruzioni che molto probabilmente si fermeranno (accesso alla memoria).
È un esempio di mancata applicazione della regola di ottimizzazione 80-20: l'ottimizzazione delle cose che sono già veloci non migliorerà significativamente le prestazioni complessive, a meno che anche le cose più lente non vengano ottimizzate.
In risposta alla risposta di Basile Starynkevitch
Non è "... (qualunque cosa) sia difficile", è che EPIC non è adatto a qualsiasi piattaforma che deve affrontare un elevato dinamismo in latenza.
Ad esempio, se un processore ha tutte le seguenti caratteristiche:
- Nessun accesso diretto alla memoria;
- Qualsiasi accesso alla memoria (lettura o scrittura) deve essere programmato tramite trasferimento DMA;
- Ogni istruzione ha la stessa latenza di esecuzione;
- Esecuzione in ordine;
- Unità di esecuzione ampie / vettoriali;
Quindi VLIW / EPIC andrà bene.
Dove si trovano tali processori? DSP. Ed è qui che VLIW è fiorito.
Con il senno di poi, il fallimento di Itanium (e il continuo riversamento dello sforzo di ricerca e sviluppo in un fallimento, nonostante l'evidenza evidente) è un esempio di fallimento organizzativo e merita di essere approfondito.
Certo, le altre iniziative del venditore, come hyperthreading, SIMD, ecc., Sembrano avere molto successo. È possibile che l'investimento in Itanium abbia avuto un effetto arricchente sulle capacità dei suoi ingegneri, il che potrebbe aver consentito loro di creare la prossima generazione di tecnologia di successo.