Che tipo di conoscenza di basso livello conta? [chiuso]

1

Mi rendo conto che questa domanda è simile a Programmazione di basso livello - Cosa c'è in esso per me , ma le risposte non rispondono davvero bene alla mia domanda. Parte da una semplice comprensione, in che modo la tua conoscenza di basso livello si traduce in programmi più veloci e migliori?

C'è l'evidente mancanza di stop-the-world dalla raccolta dei rifiuti , ma che altro è un vantaggio? Hai davvero sovraperformare il tuo compilatore di ottimizzazione? Imballate le vostre strutture dati nel modo più stretto possibile e preoccupatevi dell'allineamento? C'è una maggiore libertà in modo naturale, ma questo si traduce veramente in un programma più veloce?

    
posta Peter Smith 31.03.2012 - 02:30
fonte

5 risposte

11

Non è solo più veloce. Cicli aggiuntivi della CPU da varie penalità di stallo della pipeline della CPU e accessi extra alla memoria a causa di errori di cache e tali, in un codice critico di prestazioni sufficientemente ripetitivo, possono sommarsi per prendere energia extra misurabile. Al giorno d'oggi un grande costo nei data center è rappresentato dai costi energetici e di raffreddamento, e un grande costo nei dispositivi mobili è il peso della batteria. I transistor sono diventati quasi gratuiti, ma i nanoWat non lo sono.

Un compilatore di ottimizzazione può essere d'aiuto, ma potrebbe non conoscere tutte le possibili trasformazioni algoritmiche che possono ancora produrre un risultato utile. (ad esempio, gli esseri umani a volte sanno come imbrogliare e farla franca). Le unità matematiche corte / SIMD in molte CPU al giorno d'oggi (anche su processori di dispositivi mobili) possono spesso essere completamente utilizzate solo con una conoscenza di basso livello. / p>

I programmatori di elaborazione del segnale e incorporati usano sempre questa conoscenza di basso livello, a volte solo per soddisfare le specifiche. Se riesci a impacchettare il tuo codice per girare in un processore più economico di 10 centesimi e finisci per spedire milioni annualmente incorporati in qualche giocattolo, sei più che pagato per lo stipendio di un ingegnere del software o tre.

    
risposta data 31.03.2012 - 04:06
fonte
5

Hai ragione che alcune conoscenze di basso livello non contano. Ad esempio, penso che saresti pazzo di aritmetica di routine re-jigger per sostituire la moltiplicazione e la divisione con operazioni di bit shift equivalenti per salvare un ciclo o due. L'accelerazione dovrebbe essere microscopica, il compilatore potrebbe farlo comunque, e ho il sospetto che fare cose come triangle_area = (base >> 1) * height sia solo per chiedere guai quando qualcuno guarda il tuo codice in sei mesi. Allo stesso modo, un codice molto più vecchio salta attraverso incredibili telai per ridurre il numero di operazioni in virgola mobile; anche in questi giorni non vale la pena, il sovraccarico mentale e il potenziale per i bug.

D'altra parte, ci sono altri concetti di basso livello che possono darti guadagni relativamente grandi per un lavoro minimo. Ad esempio, prendere in considerazione la memorizzazione nella cache. Ad esempio, è possibile scorrere su una matrice NxN in questo modo:

for(i=0; i<N; ++i)
   for(j=0; j<N; ++j)
       do_something(matrix[i][j]);

o in questo modo:

for(j=0; j<N; ++j)
  for(i=0; i<N; ++i)
     do_something(matrix[i][j]);

Se la matrice è sufficientemente grande, uno di questi (a seconda di come la lingua definisce l'array) causerà un errore di cache per ogni singolo accesso dell'array, mentre l'altro sarà ottimale. Supponendo che tu debba iterare sopra la matrice in qualche modo, perché non preferire quella potenzialmente più veloce? Sono ugualmente leggibili, ugualmente scrivibili, ecc.

In generale, penso che apprezzare le cose che stanno succedendo "sotto le cappa" può aiutare a informare le tue decisioni quando si programma in linguaggi di livello superiore (ad esempio, posso codificare questo in un modo che non cancella la cache più e più volte ancora?). Se non conosci la relazione tra un indice di array e un indirizzo di memoria, potresti non apprezzare quanto sia importante controllare gli indici di array e le dimensioni del buffer. Penso che potresti raccogliere molte di queste informazioni dalla documentazione del linguaggio di livello superiore, ma sicuramente sarà più intrigante in C.

Ovviamente, il trucco non è esagerare. Esiste una differenza di velocità teorica tra i ++ e ++ i, ma se copiare una singola variabile a quattro byte crea o interrompe la tua web-app, l'app è già in difficoltà.

    
risposta data 31.03.2012 - 07:33
fonte
3

Capire come si comporta la memoria è IMO tra le cose più fruttuose. In particolare:

  • Che cache della CPU è e perché è importante.
  • Perché le primitive, e in particolare le matrici di primitive, sono più veloci di oggetti equivalenti (matrici di).
  • Perché negli array multidimensionali le righe e le colonne non sono affatto equivalenti (allineamento).
  • Barriere della memoria, operazioni di blocco contro CAS.

Anche tu puoi aiutare il compilatore di ottimizzazione: ad esempio, rendendo semplice il ciclo for attraverso un array con indici iniziali e finali espliciti può consentire al compilatore di ottimizzare il controllo del limite di distanza (che è circa l'unica cosa che rende gli array Java più lenti degli array nativi).

Come per tutte le ottimizzazioni, importa solo dove funziona:)

    
risposta data 31.03.2012 - 07:47
fonte
2

Le prestazioni non sono l'unico vantaggio di comprendere i dettagli di basso livello nel tuo programma. Ad esempio, se un'applicazione che scrivo si blocca, spesso ottengo una o più di queste cose:

  • un registro degli arresti anomali contenente un backtrace sotto forma di indirizzi sullo stack delle chiamate e il valore del contatore del programma e di altri registri
  • un core dump, contenente lo stato della memoria virtuale del processo al momento dello schianto.

Per capire cosa sta succedendo lì, hai bisogno di sapere come funziona il layout della memoria dell'architettura della CPU, le convenzioni di chiamata della piattaforma su cui è in esecuzione il codice e spesso la possibilità di leggere un disassemblaggio della piattaforma codice che appare nella traccia dello stack.

    
risposta data 31.03.2012 - 11:49
fonte
0
  • IO (file o qualsiasi altro dispositivo di output)
  • Networking (IO, ma abbastanza importante da meritare il proprio proiettile)
  • Gerarchie di memoria (capire perché è male passare da cacheA - > cacheB - > main mem - > disk)

Ovviamente tutte le cose di basso livello sono preziose a un certo livello, ma queste tre distribuiranno dividendi piuttosto buoni per un programmatore a livello di applicazione da capire. Modifica: anche questi sono luoghi in cui vengono frequentemente applicate tecniche di basso livello.

    
risposta data 01.04.2012 - 01:32
fonte

Leggi altre domande sui tag