Perché programmi in assembly? [chiuso]


86

Ho una domanda per tutti gli hacker hardcore di basso livello là fuori. Mi sono imbattuto in questa frase in un blog. Non penso davvero che la fonte sia importante (è Haack se ti interessa davvero) perché sembra essere un'affermazione comune.

Ad esempio, molti giochi 3-D moderni hanno il loro motore principale ad alte prestazioni scritto in C ++ e Assembly.

Per quanto riguarda l'assembly, il codice è scritto in assembly perché non vuoi che un compilatore emetta istruzioni extra o utilizzi byte eccessivi, o stai usando algoritmi migliori che non puoi esprimere in C (o non puoi esprimere senza il compilatore li scompiglia)?

Capisco perfettamente che è importante capire le cose di basso livello. Voglio solo capire il motivo del programma in assembly dopo averlo capito.


1
Domande simili ci sono già, credo ...
Mehrdad Afshari

8
Eeeeehh .. tecnicamente questa è una domanda diversa. Queste domande sono entrambe perché impara l'assemblaggio, ecco perché programmare in esso, che .. penso sia diverso ....?
cgp

4
Perché programmi in assembly? - Diamo un'occhiata ad alcune risposte IMPOSSIBILI a queste domande: 1) Per rendere il mio codice manutenibile, 2) flessibile, 3) per garantire la portabilità, 4) testabilità, 5) leggibilità, ...;)
ivan_ivanovich_ivanoff

9
sicurezza sul lavoro ........
San Jacinto

3
perché è divertente .. :)
RainingComputers

Risposte:


169

Penso che tu stia interpretando male questa affermazione:

Ad esempio, molti giochi 3-D moderni hanno il loro motore principale ad alte prestazioni scritto in C ++ e Assembly.

I giochi (e la maggior parte dei programmi oggigiorno) non sono "scritti in assembly" nello stesso modo in cui sono "scritti in C ++". Quel blog non sta dicendo che una parte significativa del gioco è progettata in assembly o che un team di programmatori si siede e si sviluppa in assembly come linguaggio principale.

Ciò che significa veramente è che gli sviluppatori scrivono prima il gioco e lo fanno funzionare in C ++. Quindi lo profilano, capiscono quali sono i colli di bottiglia e, se vale la pena, ottimizzano il loro controllo durante il montaggio. Oppure, se hanno già esperienza, sanno quali parti saranno colli di bottiglia e hanno pezzi ottimizzati da altri giochi che hanno costruito.

Il punto della programmazione in assembly è lo stesso di sempre: la velocità . Sarebbe ridicolo scrivere molto codice in assembler, ma ci sono alcune ottimizzazioni di cui il compilatore non è a conoscenza, e per una finestra di codice abbastanza piccola, un essere umano farà di meglio.

Ad esempio, per la virgola mobile, i compilatori tendono ad essere piuttosto conservatori e potrebbero non essere a conoscenza di alcune delle funzionalità più avanzate della tua architettura. Se sei disposto ad accettare qualche errore, di solito puoi fare meglio del compilatore, e vale la pena scrivere quel po 'di codice in assembly se trovi che viene speso molto tempo su di esso.

Ecco alcuni esempi più rilevanti:

Esempi di giochi

  • Articolo di Intel sull'ottimizzazione di un motore di gioco utilizzando elementi intrinseci SSE. Il codice finale utilizza intrinseci (non assemblatore inline), quindi la quantità di assembly puro è molto piccola. Ma guardano all'output dell'assemblatore del compilatore per capire esattamente cosa ottimizzare.

  • Radice quadrata inversa veloce di Quake . Anche in questo caso, la routine non contiene l'assembler, ma è necessario sapere qualcosa sull'architettura per eseguire questo tipo di ottimizzazione. Gli autori sanno quali operazioni sono veloci (moltiplicazione, spostamento) e quali lente (divisione, sqrt). Quindi escogitano un'implementazione molto complicata della radice quadrata che evita completamente le operazioni lente.

Elaborazione ad alte prestazioni

  • Al di fuori del dominio dei giochi, le persone nell'informatica scientifica spesso ottimizzano le cose per farle funzionare velocemente con l'hardware più recente. Pensa a questo come a giochi in cui non puoi imbrogliare la fisica.

    Un ottimo esempio recente di questo è Lattice Quantum Chromodynamics (Lattice QCD) . Questo documento descrive come il problema si riduce praticamente verso il basso per uno molto piccolo kernel computazionale, che è stato ottimizzato pesantemente per PowerPC 440 di su un IBM Blue Gene / L . Ogni 440 ha due FPU e supportano alcune operazioni ternarie speciali che sono difficili da sfruttare per i compilatori. Senza queste ottimizzazioni, Lattice QCD avrebbe funzionato molto più lentamente, il che è costoso quando il tuo problema richiede milioni di ore di CPU su macchine costose.

    Se ti stai chiedendo perché questo è importante, controlla l' articolo su Science che è uscito da questo lavoro. Usando Lattice QCD, questi ragazzi hanno calcolato la massa di un protone dai principi primi e hanno dimostrato l'anno scorso che il 90% della massa proviene da una forte energia di legame della forza e il resto dai quark. Questo è E = mc 2 in azione. Ecco un riassunto .

Per tutto quanto sopra, le applicazioni non sono progettate o scritte al 100% in assemblaggio, nemmeno vicine. Ma quando le persone hanno davvero bisogno di velocità, si concentrano sulla scrittura delle parti chiave del loro codice per volare su hardware specifico.


12
risposta sorprendente. Vorrei poterlo mettere in una wiki!
bdd

6
@Paperino ... puoi. Le domande e le risposte su StackOverflow sono attribuzioni di Creative Commons autorizzate.
Aaron Maenpaa

Per ulteriori informazioni sulla comprensione di asm per aiutarti a scrivere meglio C / C ++, vedi Perché questo codice C ++ è più veloce del mio assembly scritto a mano per testare la congettura di Collatz? . La mia risposta indica che leggere l'output asm del compilatore e modificare il codice sorgente può aiutare quando il compilatore non nota un'ottimizzazione utile. Quindi scrivi mentalmente (o effettivamente) in asm, quindi tieni in mano il compilatore per fare quello che vuoi, ma ora hai un portatile C. a prova di futuro
Peter Cordes

42

Non codifico in linguaggio assembly da molti anni, ma posso fornire diversi motivi che vedevo spesso:

  • Non tutti i compilatori possono fare uso di determinate ottimizzazioni della CPU e set di istruzioni (ad esempio, i nuovi set di istruzioni che Intel aggiunge di tanto in tanto). Aspettare che gli autori di compilatori si mettano al passo significa perdere un vantaggio competitivo.

  • Più facile abbinare il codice effettivo all'architettura e all'ottimizzazione note della CPU. Ad esempio, cose che sai sul meccanismo di recupero, caching, ecc. Questo dovrebbe essere trasparente per lo sviluppatore, ma il fatto è che non lo è, ecco perché gli autori di compilatori possono ottimizzare.

  • Alcuni accessi a livello hardware sono possibili / pratici solo tramite il linguaggio assembly (ad esempio, durante la scrittura del driver del dispositivo).

  • Il ragionamento formale a volte è effettivamente più facile per il linguaggio assembly che per il linguaggio di alto livello poiché sai già qual è il layout finale o quasi finale del codice.

  • La programmazione di alcune schede grafiche 3D (verso la fine degli anni '90) in assenza di API era spesso più pratica ed efficiente in linguaggio assembly e talvolta non era possibile in altre lingue. Ma ancora una volta, questo ha coinvolto giochi di livello davvero esperto basati sull'architettura dell'acceleratore come lo spostamento manuale dei dati dentro e fuori in un certo ordine.

Dubito che molte persone usino il linguaggio assembly quando andrebbe bene un linguaggio di livello superiore, specialmente quando quel linguaggio è C. L'ottimizzazione manuale di grandi quantità di codice generico non è pratica.


19

C'è un aspetto della programmazione in assembler che altri non hanno menzionato: la sensazione di soddisfazione che si prova sapendo che ogni singolo byte in un'applicazione è il risultato del proprio sforzo, non del compilatore. Non vorrei nemmeno per un secondo tornare a scrivere intere app in assembler come facevo all'inizio degli anni '80, ma a volte mi manca quella sensazione ...


3
Eh, è il risultato del lavoro dell'assemblatore! Di solito scrivi molte macro in asm.
Mehrdad Afshari,

5
Non solo soddisfazione, ma apprezzamento per la precisione. Un processo conciso con tutto ciò che lo riguarda dichiarato è una gioia da vedere.
deau

18

Di solito, l'assemblaggio di un laico è più lento di C (a causa dell'ottimizzazione di C) ma molti giochi (ricordo distintamente Doom ) dovevano avere sezioni specifiche del gioco in Assembly in modo che funzionasse senza problemi su macchine normali.

Ecco l'esempio a cui mi riferisco.


2
+1 Molto vero. Gli esseri umani sono molto cattivi nello scrivere codice asm lungo.
Conto morto il

Tieni presente che tali strumenti non erano sempre disponibili quando l'assemblatore è stato scritto.
Marco van de Voort

16

Ho iniziato a programmare in modo professionale in linguaggio assembly nel mio primo lavoro (anni '80). Per i sistemi embedded le richieste di memoria - RAM ed EPROM - erano basse. Potresti scrivere codice stretto che fosse facile sulle risorse.

Verso la fine degli anni '80 ero passato a C. Il codice era più facile da scrivere, eseguire il debug e mantenere. Frammenti di codice molto piccoli sono stati scritti in assembler - per me è stato quando stavo scrivendo il cambio di contesto in un RTOS roll-your-own. (Qualcosa che non dovresti più fare a meno che non sia un "progetto scientifico".)

Vedrai frammenti di assemblatore in alcuni codici del kernel Linux. Di recente l'ho esplorato in spinlock e altro codice di sincronizzazione. Questi pezzi di codice devono avere accesso alle operazioni atomiche di test e impostazione, manipolazione delle cache, ecc.

Penso che sarebbe difficile superare l'ottimizzazione dei moderni compilatori C per la maggior parte della programmazione generale.

Sono d'accordo con @altCognito sul fatto che il tuo tempo è probabilmente meglio speso a pensare più duramente al problema e fare le cose meglio. Per qualche ragione i programmatori spesso si concentrano sulle micro-efficienze e trascurano le macro-efficienze. Il linguaggio assembly per migliorare le prestazioni è una micro-efficienza. Fare un passo indietro per una visione più ampia del sistema può esporre i problemi macro in un sistema. La risoluzione dei problemi macro può spesso produrre migliori guadagni di prestazioni. Una volta risolti i problemi macro, collassare a livello micro.

Immagino che i micro problemi siano sotto il controllo di un singolo programmatore e in un dominio più piccolo. L'alterazione del comportamento a livello macro richiede la comunicazione con più persone, cosa che alcuni programmatori evitano. Tutta quella faccenda del cowboy contro la squadra.


10

"Sì". Ma capisci che per la maggior parte i vantaggi di scrivere codice in assembler non valgono lo sforzo. Il guadagno ricevuto per averlo scritto in assemblea tende ad essere inferiore rispetto al concentrarsi semplicemente sul pensare più intensamente al problema e passare il tempo a pensare a un modo migliore di fare i compiti.

John Carmack e Michael Abrash, che erano in gran parte responsabili della scrittura di Quake e di tutto il codice ad alte prestazioni che è entrato nei motori di gioco ID, approfondiscono questo dettaglio in questo libro .

Concordo anche con Ólafur Waage sul fatto che oggi i compilatori sono piuttosto intelligenti e spesso impiegano molte tecniche che sfruttano i miglioramenti architettonici nascosti.


9

Oggigiorno, almeno per i codici sequenziali, un compilatore decente batte quasi sempre anche un programmatore in linguaggio assembly molto esperto. Ma per i codici vettoriali è un'altra storia. I compilatori ampiamente distribuiti non fanno un ottimo lavoro sfruttando le capacità di parallelismo vettoriale dell'unità SSE x86, per esempio. Sono uno scrittore di compilatori e sfruttare SSE è in cima alla mia lista di motivi per andare da solo invece di fidarmi del compilatore.


In tal caso, userei un intrinseco del compilatore.
Mehrdad Afshari,

Ancora non è lo stesso. È come un compilatore senza ottimizzatore di registro
Marco van de Voort,

Dipende dal tipo di condimento del tuo programmatore asm. Se hai letto e cercato agner.org/optimize per conoscere la microarchitettura per cui stai ottimizzando, battere il compilatore solo per sequenze brevi è spesso facile . Almeno la metà delle volte vedo mancate ottimizzazioni minori quando guardo l'output del compilatore per piccole funzioni. Dove i compilatori sono fantastici è l'ottimizzazione su basi di codice di grandi dimensioni con inlining e propagazione costante.
Peter Cordes

8

Il codice SSE funziona meglio in assembly rispetto agli intrinseci del compilatore, almeno in MSVC. (cioè non crea copie extra dei dati)


Buon punto, hai bisogno di un compilatore che faccia un lavoro decente con le intrinseche. I compilatori Intel e Gnu sono abbastanza buoni, non so se le ultime novità di PGI e PathScale siano ancora competitive, non lo erano prima.
Jed

6

Ho tre o quattro routine assembler (in circa 20 MB di sorgente) nei miei sorgenti al lavoro. Sono tutti SSE (2) e sono correlati alle operazioni su immagini (abbastanza grandi - si pensi a 2400x2048 e più grandi).

Per hobby, lavoro su un compilatore e lì hai più assemblatore. Le librerie runtime sono abbastanza spesso piene di loro, la maggior parte di esse ha a che fare con cose che sfida il normale regime procedurale (come helper per eccezioni ecc.)

Non ho alcun assemblatore per il mio microcontrollore. La maggior parte dei microcontrollori moderni ha così tanto hardware periferico (contatori controllati da interrupt, persino interi encoder in quadratura e blocchi di costruzione seriali) che spesso non è più necessario utilizzare l'assembler per ottimizzare i loop. Con gli attuali prezzi flash, lo stesso vale per la memoria del codice. Inoltre ci sono spesso gamme di dispositivi compatibili con i pin, quindi l'upscaling se si esaurisce sistematicamente l'alimentazione della CPU o lo spazio flash spesso non è un problema

A meno che non si spediscano davvero 100000 dispositivi e l'assemblatore di programmazione rende possibile ottenere risparmi davvero importanti semplicemente inserendo un chip flash di una categoria più piccola. Ma non sono in quella categoria.

Molte persone pensano che embedded sia una scusa per l'assemblatore, ma i loro controller hanno più potenza della CPU rispetto alle macchine su cui è stato sviluppato Unix . (Microchip in dotazione con microcontrollori da 40 e 60 MIPS per meno di 10 USD ).

Tuttavia molte persone sono bloccate con l'eredità, dal momento che cambiare l'architettura del microchip non è facile. Anche il codice HLL dipende molto dall'architettura (perché utilizza la periferica hardware, i registri per controllare l'I / O, ecc.). Quindi a volte ci sono buone ragioni per continuare a mantenere un progetto in assembler (sono stato fortunato ad essere in grado di impostare gli affari su una nuova architettura da zero). Ma spesso le persone si illudono di aver davvero bisogno dell'assemblatore.

Mi piace ancora la risposta data da un professore quando abbiamo chiesto se potevamo usare GOTO (ma potresti leggerlo anche come ASSEMBLER): "se pensi che valga la pena scrivere un saggio di 3 pagine sul motivo per cui hai bisogno della funzione, puoi usarlo . Invia il saggio con i tuoi risultati. "

L'ho usato come principio guida per le funzionalità di basso livello. Non essere troppo angusto per usarlo, ma assicurati di motivarlo adeguatamente. Alza anche una o due barriere artificiali (come il saggio) per evitare ragionamenti contorti come giustificazione.


1
Mi piace il saggio di prova; Potrei aver bisogno di usarlo più spesso;)
ex nihilo

5

Alcune istruzioni / flag / controlli semplicemente non sono presenti a livello C.

Ad esempio, il controllo dell'overflow su x86 è il semplice flag di overflow. Questa opzione non è disponibile in C.


È possibile calcolare flag di overflow in C con operazioni sui bit.
swegi

@swegi: scommetto che è insignificantemente più lento.
Brian

quanto spesso è utile? e quando lo è, non può essere l'unico motivo per entrare in assembler.

5

I difetti tendono a essere eseguiti per riga (istruzione, punto di codice, ecc.); mentre è vero che per la maggior parte dei problemi, l'assembly userebbe molte più righe rispetto ai linguaggi di livello superiore, a volte ci sono casi in cui è la migliore (più concisa, meno righe) mappata al problema in questione. La maggior parte di questi casi coinvolge i soliti sospetti, come driver e bit-bang nei sistemi embedded.


3

Un altro motivo potrebbe essere quando il compilatore disponibile non è abbastanza buono per un'architettura e la quantità di codice necessaria nel programma non è così lunga o complessa da permettere al programmatore di perdersi in essa. Prova a programmare un microcontrollore per un sistema embedded, di solito l'assemblaggio sarà molto più semplice.


3

Oltre ad altre cose menzionate, tutte le lingue superiori hanno alcune limitazioni. Ecco perché alcune persone scelgono di programmare in ASM, per avere il pieno controllo del proprio codice.

Altri godono di eseguibili molto piccoli, nella gamma di 20-60 KB, ad esempio controlla HiEditor , che è implementato dall'autore del controllo HiEdit, superbo controllo di modifica potente per Windows con evidenziazione della sintassi e schede in soli ~ 50kb). Nella mia collezione ho più di 20 controlli di questo tipo da Excell come ssheets a rendering HTML.


3

Penso che molti sviluppatori di giochi sarebbero sorpresi da questa informazione.

La maggior parte dei giochi che conosco utilizza il minor numero di assembly possibile. In alcuni casi nessuno e, nel peggiore dei casi, uno o due cicli o funzioni.

Quella citazione è eccessivamente generalizzata e non è neanche lontanamente vera come lo era dieci anni fa.

Ma hey, i semplici fatti non dovrebbero ostacolare la crociata di un vero hacker a favore dell'assemblaggio. ;)


3

Se stai programmando un microcontrollore a 8 bit di fascia bassa con 128 byte di RAM e 4K di memoria del programma, non hai molta scelta sull'uso dell'assembly. A volte, però, quando si utilizza un microcontrollore più potente è necessario che una determinata azione avvenga in un momento esatto. Il linguaggio Assembly è quindi utile poiché puoi contare le istruzioni e quindi misurare i cicli di clock utilizzati dal tuo codice.


2

Se fossi stato in giro per tutti gli sforzi di riparazione del 2000, avresti potuto guadagnare molti soldi se avessi conosciuto Assembly. C'è ancora molto codice legacy in giro che è stato scritto in esso e quel codice a volte necessita di manutenzione.


2

A parte progetti molto piccoli su CPU molto piccole, non mi prefiggo di programmare mai un intero progetto in assembly. Tuttavia, è comune scoprire che un collo di bottiglia delle prestazioni può essere alleviato con la codifica manuale strategica di alcuni loop interni.

In alcuni casi, tutto ciò che è realmente richiesto è sostituire un costrutto di linguaggio con un'istruzione che non ci si può aspettare che l'ottimizzatore capisca come usare. Un tipico esempio è nelle applicazioni DSP in cui le operazioni vettoriali e le operazioni di accumulazione multipla sono difficili da scoprire per un ottimizzatore, ma sono facili da gestire.

Ad esempio, alcuni modelli di SH4 contengono una matrice 4x4 e 4 istruzioni vettoriali. Ho visto un enorme miglioramento delle prestazioni in un algoritmo di correzione del colore sostituendo le operazioni C equivalenti su una matrice 3x3 con le istruzioni appropriate, al piccolo costo di ingrandire la matrice di correzione a 4x4 per abbinare i presupposti hardware. Ciò è stato ottenuto scrivendo non più di una dozzina di righe di assemblaggio e portando le modifiche di corrispondenza ai tipi di dati correlati e l'archiviazione in una manciata di punti nel codice C circostante.


2

Non sembra essere menzionato, quindi ho pensato di aggiungerlo: nello sviluppo di giochi moderni, penso che almeno parte dell'assembly che viene scritto non sia affatto per la CPU. È per la GPU, sotto forma di programmi shader .

Ciò potrebbe essere necessario per tutti i tipi di motivi, a volte semplicemente perché qualunque linguaggio di ombreggiatura di livello superiore utilizzato non consente di esprimere l'operazione esatta nel numero esatto di istruzioni desiderate, per adattarsi a qualche vincolo di dimensione, velocità o qualsiasi combinazione . Proprio come al solito con la programmazione in linguaggio assembly, immagino.


2

Quasi tutti i motori di gioco o le librerie di dimensioni medio-grandi che ho visto fino ad oggi hanno alcune versioni di assembly ottimizzate manualmente disponibili per operazioni con matrici come la concatenazione di matrici 4x4. Sembra che i compilatori perdano inevitabilmente alcune delle ottimizzazioni intelligenti (riutilizzare i registri, srotolare i loop in modo massimamente efficiente, trarre vantaggio dalle istruzioni specifiche della macchina, ecc.) Quando si lavora con matrici di grandi dimensioni. Anche queste funzioni di manipolazione della matrice sono quasi sempre "punti caldi" sul profilo.

Ho anche visto un assembly codificato a mano utilizzato molto per l'invio personalizzato, cose come FastDelegate, ma specifiche del compilatore e della macchina.

Infine, se hai le routine di interrupt del servizio, asm può fare la differenza nel mondo - ci sono alcune operazioni che semplicemente non vuoi che avvengano sotto interrupt, e vuoi che i tuoi gestori di interrupt "entrino ed escano velocemente". .. sai quasi esattamente cosa succederà nella tua ISR se è in asm, e ti incoraggia a mantenere le cose insanguinate brevi (che è comunque una buona pratica).


2

I giochi sono piuttosto assetati di prestazioni e sebbene nel frattempo gli ottimizzatori siano abbastanza buoni, un "programmatore esperto" è ancora in grado di ottenere prestazioni in più codificando manualmente le parti giuste in assembly.

Non iniziare mai a ottimizzare il tuo programma senza prima profilarlo. Dopo la profilazione dovrebbe essere in grado di identificare i colli di bottiglia e se la ricerca di algoritmi migliori e simili non funziona più, puoi provare a codificare a mano alcune cose in assembly.


2

Ho parlato personalmente solo con uno sviluppatore del suo uso dell'assembly. Stava lavorando al firmware che si occupava dei controlli per un lettore mp3 portatile. Fare il lavoro in assemblaggio aveva 2 scopi:

  1. Velocità: i ritardi dovevano essere minimi.
  2. Costo: essendo minimo con il codice, l'hardware necessario per eseguirlo potrebbe essere leggermente meno potente. Quando si producono in serie milioni di unità, questo può sommarsi.

2

L'unico codice assembler che continuo a fare è per l'hardware incorporato con poche risorse. Come menzionato da Leander, l'assemblaggio è ancora adatto agli ISR in cui il codice deve essere veloce e ben compreso.

Una ragione secondaria per me è mantenere le mie conoscenze sull'assemblaggio funzionali. Essere in grado di esaminare e comprendere i passaggi che la CPU sta eseguendo per eseguire le mie offerte è semplicemente piacevole.


2

L'ultima volta che ho scritto in assembler è stato quando non sono riuscito a convincere il compilatore a generare codice libero da libc e indipendente dalla posizione.

La prossima volta sarà probabilmente per lo stesso motivo.

Ovviamente avevo altri motivi .


2

Molte persone amano denigrare il linguaggio assembly perché non hanno mai imparato a programmare con esso e l'hanno incontrato solo vagamente e li ha lasciati sbalorditi o un po 'intimiditi. I veri programmatori di talento capiranno che non ha senso colpire C o Assembly perché sono complementari. infatti il ​​vantaggio di uno è lo svantaggio dell'altro. Le regole sintattiche organizzate di C migliorano la chiarezza ma allo stesso tempo rinuncia a tutto ciò che l'assieme di potenza ha dall'essere libero da qualsiasi regola strutturale! Le istruzioni del codice C sono fatte per creare codice non bloccante che potrebbe essere sostenuto forza la chiarezza dell'intento di programmazione, ma questa è una perdita di potenza. In C il compilatore non consentirà un salto all'interno di un if / elseif / else / end. Oppure non è consentito scrivere due cicli for / end su variabili diverse che si sovrappongono tra loro, non puoi scrivere codice che si modifichi da solo (o non puoi farlo in un modo semplice e senza soluzione di continuità), ecc. . Ecco la verità: oggi abbiamo macchine con la potenza di calcolo per fare molto di più dell'applicazione per cui le usiamo, ma il cervello umano è troppo incapace di codificarle in un ambiente di codifica senza regole (= assemblaggio) e ha bisogno di regole restrittive molto riduce lo spettro e semplifica la codifica. Ho scritto codice che non può essere scritto in codice C senza diventare estremamente inefficiente a causa delle limitazioni sopra menzionate. E non ho ancora parlato della velocità che la maggior parte delle persone pensa sia la ragione principale per scrivere in assembly, beh, se la tua mente è limitata a pensare in C, allora sei lo schiavo del tuo compilatore per sempre. Ho sempre pensato che i maestri dei giocatori di scacchi sarebbero stati programmatori di assembly ideali mentre i programmatori in C giocano solo a "Dames".


1
il codice di auto-modifica non è utile per le prestazioni sulla maggior parte delle CPU moderne, al di fuori degli scenari JIT-once / run-many. Ma riempire le costanti come immediate è una possibilità divertente. gotoTuttavia, il C consente salti non strutturati all'interno di una funzione. Includere in un blocco all'interno di un if()ciclo o nella stessa funzione. ad es . godbolt.org/z/IINHTg . Vedi anche il dispositivo di Duff, usando interruttore / custodia in un do{}while()loop per esprimere un salto in un loop srotolato. Ma a un certo punto può diventare più chiaro scrivere in asm se stai arrivando a quel livello di confusione.
Peter Cordes

1
(Ovviamente, il dispositivo di Duff è utile solo su macchine con indirizzamento post-incremento, altrimenti quei punti di ingresso all'interno del ciclo srotolato annullano la maggior parte dello scopo dell'ottimizzazione.)
Peter Cordes

1

Non più velocità, ma controllo . La velocità a volte verrà dal controllo, ma è l' unica ragione per codificare in assembly. Ogni altra ragione si riduce al controllo (ad es. SSE e altre ottimizzazioni manuali, driver di dispositivo e codice dipendente dal dispositivo, ecc.).


1

Se sono in grado di superare GCC e Visual C ++ 2008 (noto anche come Visual C ++ 9.0), le persone saranno interessate a intervistarmi su come sia possibile.

Questo è il motivo per cui per il momento leggo le cose in assembly e scrivo __asm ​​int 3 quando richiesto.

Spero che questo aiuto ...


1

Non scrivo in assemblea da alcuni anni, ma i due motivi per cui ero solito erano:

  • La sfida della cosa! Ho attraversato un periodo di diversi mesi anni fa, quando scrivevo tutto in assembly x86 (i tempi di DOS e Windows 3.1). Fondamentalmente mi ha insegnato un po 'di operazioni di basso livello, I / O hardware , ecc.
  • Per alcune cose ha mantenuto le dimensioni ridotte (di nuovo DOS e Windows 3.1 durante la scrittura di TSR )

Continuo a guardare di nuovo all'assemblaggio del codice, e non è altro che la sfida e la gioia della cosa. Non ho altri motivi per farlo :-)


1

Una volta ho rilevato un progetto DSP che il programmatore precedente aveva scritto principalmente in codice assembly, ad eccezione della logica di rilevamento del tono che era stata scritta in C, utilizzando la virgola mobile (su un DSP a virgola fissa!). La logica di rilevamento del tono ha funzionato a circa 1/20 del tempo reale.

Ho finito per riscrivere quasi tutto da zero. Quasi tutto era in C ad eccezione di alcuni piccoli gestori di interrupt e poche dozzine di righe di codice relative alla gestione degli interrupt e al rilevamento della frequenza di basso livello, che viene eseguito più di 100 volte più velocemente del vecchio codice.

Una cosa importante da tenere a mente, penso, è che in molti casi, ci saranno molte maggiori opportunità per il miglioramento della velocità con routine piccole rispetto a quelle grandi, specialmente se l'assemblatore scritto a mano può contenere tutto nei registri ma un compilatore non lo farebbe abbastanza gestire. Se un ciclo è abbastanza grande da non poter comunque tenere tutto nei registri, ci sono molte meno opportunità di miglioramento.


0

La VM Dalvik che interpreta il bytecode per le applicazioni Java sui telefoni Android utilizza l'assembler per il dispatcher. Questo film (circa 31 minuti dopo, ma vale la pena guardare l'intero film!) Spiega come

"ci sono ancora casi in cui un essere umano può fare meglio di un compilatore".


0

Non lo faccio, ma ho deciso di provarci almeno e di impegnarmi a un certo punto in futuro (presto si spera). Non può essere una brutta cosa conoscere meglio le cose di basso livello e come funzionano le cose dietro le quinte quando sto programmando in un linguaggio di alto livello. Purtroppo il tempo è difficile da trovare con un lavoro a tempo pieno come sviluppatore / consulente e genitore. Ma mi arrenderò a tempo debito, questo è certo.

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.