Domanda

Scrivi una funzione e, guardando l'assembly risultante, vedi che può essere migliorata.

Vorresti mantenere la funzione che hai scritto, per la leggibilità, ma vorresti sostituire il tuo assembly con quello del compilatore.Esiste un modo per stabilire una relazione tra la tua funzione linguistica di alto livello e la nuova assemblea?

È stato utile?

Soluzione

Se stai osservando l'assembly, è giusto presumere che tu abbia una buona conoscenza di come viene compilato il codice.Se si dispone di questa conoscenza, a volte è possibile eseguire il "reverse engineering" delle modifiche riportandole nella lingua originale, ma spesso è meglio non preoccuparsi.

È probabile che le ottimizzazioni apportate siano molto piccole rispetto al tempo e allo sforzo necessari per apportare inizialmente queste modifiche.Ti suggerirei di lasciare questo tipo di lavoro al compilatore e di andare a prendere una tazza di tè.Se i cambiamenti sono significativi e le prestazioni sono critiche (come nel mondo embedded), allora potresti voler mescolare in qualche modo il codice normale con l'assemblatore, tuttavia, sulla maggior parte dei computer e dei chip le prestazioni sono solitamente sufficienti per evitare questo mal di testa.

Se tu Veramente hai bisogno di più prestazioni, quindi ottimizza il codice e non l'assembly.

Altri suggerimenti

Nessuno, suppongo.Hai rifiutato il lavoro del compilatore a favore del tuo.Potresti anche eliminare la funzione che hai scritto nel linguaggio compilato, perché ora tutto ciò che hai è il tuo assemblatore in quella piattaforma.

Sconsiglio vivamente di impegnarsi in questo tipo di ottimizzazione perché a meno che tu non sia sicuro, tramite profilazione e analisi, di stare davvero facendo la differenza.

Dipende dalla lingua in cui hai scritto la funzione.Alcuni linguaggi come il C sono di livello molto basso e traducono ogni chiamata di funzione o istruzione in specifiche istruzioni di assembly.Se hai utilizzato C, puoi sostituire la tua funzione con un assembly inline per migliorare le prestazioni.

Altri linguaggi di alto livello possono convertire ciascuna istruzione in macro routine o altre chiamate più complesse dal lato assembly.Alcune ottimizzazioni (come la ricorsione in coda, lo srotolamento del loop, ecc.) possono essere implementate facilmente sul lato sorgente, ma altre (come un uso più efficiente del file di registro) potrebbero essere impossibili (di nuovo, a seconda del linguaggio e del compilatore che stai utilizzando utilizzando).

È difficile dire che esista una relazione tra l'assembly modificato e la fonte che ha generato la versione non modificata.Sicuramente confonderà gli strumenti di debug:il contenuto dei registri non corrisponderà più alle variabili sorgente a cui avrebbero dovuto corrispondere.

Esistono diversi punti nel codice di elaborazione dei pacchetti in cui ho esaminato l'assembly generato e sono tornato per modificare il codice sorgente originale per migliorare il risultato.La riorganizzazione del sorgente può ridurre il numero di rami, __attribute__ e gli argomenti del compilatore possono allineare punti di diramazione e funzioni per ridurre i mancati I$.In casi disperati può essere utilizzato un piccolo assembly inline, in modo che il binario possa ancora essere compilato dal sorgente.

Qualcosa che potresti provare è separare la tua funzione originale in un proprio file e fornire una regola make per costruire l'assemblatore da lì.Quindi aggiorna il file assembler con la versione migliorata e fornisci una regola make per creare un file oggetto dal file assembler.Quindi modifica le regole di collegamento per includere quel file oggetto.

Se cambi solo il file assembler, quello continuerà a essere utilizzato.Se si modifica il file di lingua originale di livello superiore, il file assembler verrà ricostruito e il file oggetto verrà creato dalla nuova versione (non migliorata).

Questo ti dà una relazione tra i due;probabilmente vorrai aggiungere un commento di avviso nella parte superiore del file di lingua di livello superiore per avvisare del comportamento.Usare qualche forma di VCS ti darà la possibilità di recuperare il file assembler migliorato se commetti un errore qui.

Se stai scrivendo un'app compilata nativa in Visual C++, sono disponibili due metodi:

  1. Usa il __asm { } blocca e scrivi lì il tuo assembler.
  2. Scrivi le tue funzioni in MASM assembler, assemblare in .obj e collegarlo come libreria statica.Nel codice C/C++ dichiara la funzione con an extern "C" dichiarazione.

Altri compilatori C/C++ hanno approcci simili.

In questa situazione, generalmente hai due opzioni:ottimizzare il codice o riscrivere il compilatore.Non riesco a vedere dove interrompere il collegamento tra sorgente e operazione sarà mai la soluzione corretta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top