Latenza delle istruzioni della CPU sui processori x86 e x64


14

Sto cercando una tabella o qualcosa di simile che possa aiutarmi a calcolare l'efficienza del codice assembly.

Come so, lo spostamento dei bit richiede 1 clock della CPU, ma sto davvero osservando quanto richiede l'addizione (la sottrazione dovrebbe richiedere lo stesso), la moltiplicazione e come presumibilmente calcolare il tempo di divisione se conosco valori che stanno dividendo.

Ho davvero bisogno di informazioni sui valori interi, ma anche i tempi di esecuzione float sono i benvenuti.


Risposte:


10

In generale, ciascuna di queste operazioni richiede anche un singolo ciclo di clock per essere eseguita se gli argomenti sono nei registri nelle varie fasi della pipeline.

Cosa intendi per latenza? Quanti cicli trascorre un'operazione nell'ALU?

Questa tabella potrebbe essere utile: http://www.agner.org/optimize/instruction_tables.pdf

Poiché i processori moderni sono super scalari e possono essere eseguiti in modo anomalo, spesso è possibile ottenere istruzioni totali per ciclo che superano 1. Gli argomenti per il comando macro sono i più importanti, ma l'operazione conta anche poiché le divisioni richiedono più tempo di XOR (<1 latenza del ciclo).

Molte istruzioni x86 possono richiedere più cicli per completare alcune fasi se sono complesse (ad esempio comandi REP o MWAIT peggiori).


3
La moltiplicazione dei numeri interi è almeno 3c di latenza su tutte le recenti CPU x86 (e superiore su alcune CPU meno recenti). Su molte CPU è completamente pipeline, quindi il throughput è 1 per clock, ma puoi ottenerlo solo se hai tre moltiplicazioni indipendenti in volo. (Moltiplicare FP su Haswell è latenza 5c, throughput 0,5c, quindi sono necessari 10 in volo per saturare il throughput). La divisione ( dive idiv) è anche peggio: è microcodificata e ha una latenza molto più alta di addo shr, e non è nemmeno completamente pipeline su alcuna CPU. Tutto questo è direttamente dalle tabelle di istruzioni di Agner Fog, quindi è una buona cosa che tu l'abbia collegato.
Peter Cordes,


7

Il calcolo dell'efficienza del codice assembly non è il modo migliore per procedere in questi giorni con le pipeline super scalari Ex of Order Execution. Varia in base al tipo di processore. Varia in base alle istruzioni sia prima che dopo (puoi aggiungere del codice extra e farlo funzionare più velocemente a volte!). Alcune operazioni (in particolare la divisione) possono avere una gamma di tempi di esecuzione anche su chip più vecchi e prevedibili. In realtà il tempismo di molte iterazioni è l'unica strada da percorrere.


Lo so, ma non ne ho bisogno in un vero progetto, ma in un certo senso un divertente progetto di programmazione.
ST3,

Se ne hai bisogno per davvero o per divertimento non cambia la risposta per questa linea di processori. Hai preso in considerazione il passaggio a un processore più deterministico, come un chip Propeller, invece?
Brian Knoblauch,

3
Anche con un ramo di implementazione scalare e in ordine, errori di previsione e errori nella cache possono causare variazioni nel tempo di esecuzione.
Paul A. Clayton,

Per cose puramente legate alla CPU (nessuna mancanza di cache, nessun errore di ramo), il comportamento della CPU è compreso in modo sufficientemente dettagliato che l'analisi statica può spesso prevedere quasi esattamente quanti cicli per iterazione un ciclo prenderà su una CPU specifica (ad esempio Intel Haswell). ad es. vedere questa risposta SO dove guardare l'asm generato dal compilatore mi spiego perché la versione ramificata ha funzionato quasi esattamente 1,5 volte più velocemente della versione CMOV sulla CPU Sandybridge dell'OP, ma molto più vicino sul mio Skylake.
Peter Cordes,

Se stai scrivendo asm a mano per motivi di prestazioni, è effettivamente utile cercare i colli di bottiglia di latenza e throughput su CPU Intel e AMD. È difficile, tuttavia, e talvolta ciò che è ottimale per AMD non è ciò che è ottimale per Intel.
Peter Cordes,

4

Puoi trovare informazioni su CPU Intel nei manuali per sviluppatori di software Intel . Ad esempio la latenza è 1 ciclo per un'aggiunta di numeri interi e 3 cicli per una moltiplicazione di numeri interi.

Non conosco la moltiplicazione, ma mi aspetto che l'addizione prenda sempre un ciclo.


Un ciclo, tranne quando è "libero" (in parallelo quando le tubazioni si allineano correttamente) o impiega più tempo a causa di un errore nella cache. :-)
Brian Knoblauch,

2
Attualmente (2018) queste informazioni sono disponibili nell'Appendice C denominata "Latenza e throughput delle istruzioni" del documento 248966 "Manuale di riferimento per l'ottimizzazione delle architetture Intel® 64 e IA-32" disponibile anche sulla pagina collegata nella risposta
stefanct
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.