Come valutare l'efficienza del codice assembler?

0

Stavo codificando alcune funzioni in C ++ e mi chiedevo in che modo diverse versioni di quelle funzioni avrebbero influito sul codice di assembly generato. Ho inserito diverse versioni nello strumento Explorer del compilatore di Godbolt e ho esaminato l'assemblaggio generato. È stata un'esperienza interessante vedere queste differenze e alcune versioni che sembravano essere più efficienti occupano molte più linee di assemblaggio di quelle più prolisse e, al contrario, alcune versioni di livello più basso occupano più di alcune versioni "di medio livello" (contrariamente alle mie aspettative).

Dato che non si può giudicare la performance di queste uscite guardando solo il conteggio delle righe, mi sono chiesto come si possa stimare approssimativamente la differenza di prestazioni tra diverse versioni?

Come posso analizzare diversi output per vedere più facilmente se qualche output di codice contiene più potenziali chiamate ASM costose di un altro output o devo prima imparare assembly per fare questo?

    
posta TorbenJ 10.09.2017 - 23:10
fonte

4 risposte

6

Come altri hanno sottolineato, il solo conteggio dei cicli di clock delle istruzioni assembler non ti darà un risultato decente per la maggior parte delle architetture CPU moderne. Il tempo di esecuzione di un codice pezzo fisso può variare su diverse piattaforme CPU, anche se il codice è esattamente lo stesso. Quindi l'unico modo affidabile per confrontare le prestazioni di tali frammenti di codice è

  • scarica i compilatori che vuoi confrontare
  • ottieni uno o più hardware e amp; Piattaforme SO per i confronti
  • incorpora i frammenti di codice che desideri confrontare in qualche programma di benchmark (nella sua forma più semplice: solo un ciclo che chiama lo snippet diverse milioni di volte e misura il tempo di esecuzione totale)
  • compila il benchmark con ciascuno dei compilatori, utilizzando le opzioni di ottimizzazione disponibili (forse su misura per ciascuna delle piattaforme che vuoi confrontare)
  • quindi esegui i programmi e misura su ogni piattaforma

Ovviamente, l'apprendimento dell'assemblaggio non è obbligatorio per questo processo (ma sarà probabilmente necessario se si desidera comprendere la causa principale delle differenze di prestazioni che si osserveranno).

Probabilmente non è la risposta che volevi sentire, suppongo che ti aspettassi un riferimento a qualche tipo di servizio web come il sito di Mr Godbolt che ti fornisce gli strumenti e l'hardware, quindi non devi comprare e installare loro da soli. Tuttavia, non penso che sia disponibile un servizio gratuito: i confronti sensibili delle prestazioni richiedono hardware reale e costoso, non una sostituzione economica delle macchine virtuali, e qualsiasi azienda che possa fare questo per te probabilmente cercherà di ottenere un rendimento decente dal loro investimento .

    
risposta data 11.09.2017 - 11:58
fonte
3

Ci sono due difetti nel tuo processo:

  • Stai testando uno strumento specifico (Godbolt Compiler Explorer Tool) e osservando il suo output, che sarà sicuramente diverso dall'output di un compilatore di qualità di produzione (e che dipende anche molto dalle impostazioni di ottimizzazione che scegli).
  • Con le moderne CPU, è praticamente impossibile prevedere il tempo di esecuzione semplicemente leggendo il codice assembly.

Infine, il consiglio generale sull'ottimizzazione delle prestazioni: fallo solo quando hai trovato che è necessario.

  • Inizia con la scrittura di un codice ben strutturato e leggibile
  • Decidi se c'è qualche problema di prestazioni. E "se non è rotto, non aggiustarlo".
  • Se c'è un problema, usa un profiler per scoprire il vero collo di bottiglia (scommetto che ti sorprenderà dov'è).
  • Trova una soluzione per quel collo di bottiglia (magari per micro-ottimizzazione, magari cambiando il tuo algoritmo ...)
  • Nuovo profilo, per verificare se la tua modifica ha funzionato davvero.
  • Se è ancora troppo lento, ripeti con il collo di bottiglia successivo.
risposta data 11.09.2017 - 10:09
fonte
2

Prima di tutto: le prestazioni dipendono dall'ottimizzazione che il compilatore farà sul tuo codice, quindi potresti voler testare il compilatore che userai per creare il programma finale.

Inoltre, dovrai testare il tuo codice per ogni produttore e chipset principale perché la lingua dell'assembly è diversa e le istruzioni simili possono essere gestite in modo abbastanza diverso.

    
risposta data 11.09.2017 - 08:14
fonte
2

I was coding some functions in C++ and wondered how different versions of those functions would affect generated assembly code.

E ora sai che è difficile. Era solo una curiosità oziosa e hai davvero bisogno di sapere quanto è veloce.

Ho avuto persone che mi chiedono quale sia più veloce

x = x + 1; x += 1; or x++;

Qualsiasi compilatore decente probabilmente genererà lo stesso codice. E il tuo programma ha un problema serio se l'incremento di una variabile è un problema di prestazioni ...

    
risposta data 11.09.2017 - 14:14
fonte

Leggi altre domande sui tag