E 'necessario capire cosa sta succedendo a livello hardware per essere un buon programmatore?

23

Sono un programmatore autodidatta, nel caso in cui a questa domanda sia stata data risposta in CS 101. Ho imparato e utilizzato molte lingue, principalmente per uso personale, ma occasionalmente per contenuti professionali.

Sembra che mi imbatti sempre nello stesso muro quando corro problemi di programmazione. Ad esempio, ho appena fatto una domanda su un altro forum su come gestire un puntatore a array che è stato restituito da una funzione. Inizialmente penso che semplicemente non conosca la tecnica corretta che i progettisti di C ++ hanno configurato per gestire la situazione. Ma dalle risposte e dalle discussioni che seguono, vedo che non capisco cosa succede quando qualcosa viene "restituito".

Quanto deve essere profondo un livello di comprensione del processo di programmazione per un buon programmatore?

    
posta bev 18.10.2011 - 00:23
fonte

8 risposte

31

No. Nessuno capisce cosa sta succedendo a livello hardware.

I sistemi informatici sono come le cipolle: ci sono molti livelli e ognuno dipende dal livello sottostante per il supporto. Se sei il tipo che lavora su uno degli strati più esterni, non dovresti preoccuparti troppo di ciò che accade nel mezzo della cipolla. E questa è una buona cosa, perché il centro della cipolla cambia sempre. Finché il livello o i livelli che supportano il tuo particolare livello continuano a sembrare uguali e supportano il tuo livello, sei a posto.

Ma poi di nuovo ...

Sì. Voglio dire, non hai bisogno di capire cosa sta succedendo realmente all'interno della cipolla, ma aiuta molto ad avere un modello mentale di ciò che è dentro di una cipolla tipica sembra. Forse non la parte più profonda, dove hai cancelli fatti di transistor e simili, o il prossimo strato o due, dove hai microcodice, un orologio, unità di decodifica delle istruzioni ecc. Gli strati successivi, però, sono dove tu Hai registri, lo stack e l'heap. Questi sono gli strati più profondi in cui hai molta influenza su ciò che accade: il compilatore traduce il tuo codice in istruzioni che vengono eseguite a questo livello e, se lo desideri, puoi solitamente seguire queste istruzioni e scoprire cosa sta "realmente" accadendo.

I programmatori più esperti hanno una versione leggermente fiabesca di questi strati nella loro testa. Ti aiutano a capire di cosa parla il compilatore quando ti dice che c'è stata un'eccezione di "indirizzo non valido" o un "errore di overflow dello stack" o qualcosa del genere.

Se sei interessato, leggi un libro sull'architettura del computer. Non ha nemmeno bisogno di essere un libro particolarmente nuovo - i computer digitali hanno funzionato all'incirca nello stesso modo per molto tempo. Più imparerai l'interno della cipolla, più sarai sbalordito che nessuna di queste cose funzioni! Apprendere (approssimativamente) ciò che accade negli strati inferiori rende la programmazione meno misteriosa e, in qualche modo, più magica. E davvero, più divertente.

Un'altra cosa che potresti esaminare sono le cipolle incorporate. Er, intendo sistemi incorporati. Esistono numerose piattaforme incorporate che sono piuttosto facili da usare: Arduino e BASIC Stamp sono due esempi. Questi sono microprocessori di piccole dimensioni con molte funzionalità integrate. Puoi considerarli come cipolle con meno livelli rispetto al tuo tipico PC desktop, quindi è possibile ottenere una conoscenza approfondita di ciò che sta accadendo nell'intero sistema, dall'hardware fino al software.

    
risposta data 18.10.2011 - 00:58
fonte
10

Non parli del livello hardware, stai parlando di ciò che il compilatore fa davvero con ciò che gli dici di fare.

Sicuramente hai bisogno di questo livello di comprensione per capire cosa è andato storto quando non è ovvio, specialmente quando si tratta di una situazione di stomp della memoria.

    
risposta data 18.10.2011 - 00:28
fonte
6

Informazioni sulla memoria del programma! = Informazioni sull'hardware

Informazioni sulla gerarchia di memoria == Informazioni sull'hardware

Per rispondere alla tua domanda generica: dipende. Non può far male capire l'hardware, ma comprenderlo non sarà di aiuto in tutti i casi.

Sulla base del tuo esempio, devi solo capire di più su come la memoria è divisa e come è organizzata quando stai eseguendo un programma. Comprendere l'hardware non ti aiuterà in questo senso, perché la memoria (come visibile ad un programma) non rappresenta nemmeno l'hardware grazie alla magia della memoria virtuale.

Se ti interessano i problemi di prestazioni basati sull'ordine in cui accedi alla memoria, ADESSO ti trarrai vantaggio dalla comprensione dell'hardware, dell'erarchia della memoria, dei problemi di cache, degli errori di pagina e di tutta la gloriosa bontà che proviene dall'hardware.

    
risposta data 18.10.2011 - 00:31
fonte
5

Se fai decide di imparare un po 'di assemblatore, dovresti probabilmente imparare qualcosa come 6502 assembler su un Commodore 64 (emulato, ovviamente) o 68000 su un Amiga.

Puoi avere un'idea del Commodore 64 qui ...

link

Il classico libro tutto-di-cui-sai-conoscere è quello descritto qui ...

link

Probabilmente puoi trovare una scansione PDF se ti guardi intorno.

IMO, 6502 è più facile di Z80 e 68000 è più semplice di 8086 - più set di istruzioni regolari ecc.

Ma la CPU è solo un aspetto dell'hardware. Inoltre, una CPU moderna è una bestia enormemente diversa e fa cose che sono trasparenti anche dal punto di vista dei compilatori, come la presentazione di uno spazio di indirizzi virtuali.

Un particolare vantaggio del 6502 sul C64 è che non solo la CPU è semplice, ma c'è anche un modo molto semplice di hackerare l'hardware. Mi divertivo molto a giocare con il chip musicale SID.

Quindi - probabilmente è un esercizio utile se non ci passi troppo tempo. Ho imparato 6502 assembler come seconda lingua quando avevo circa 14 anni, subito dopo Commodore Basic. Ma soprattutto sta ottenendo un modello di lavoro molto semplice in modo da poter aggiungere idee più sofisticate ad esso con un minimo di incomprensioni.

Alcune cose utili che puoi imparare lavorando nell'assemblatore ...

  • Come funzionano i registri della CPU.
  • Come funziona l'indirizzamento della memoria, incluso l'indirizzamento indiretto.
  • Come funziona lo stack della CPU.
  • Come funziona la logica bit a bit.
  • Come la CPU controlla i dispositivi I / O.
  • Come funzionano gli interrupt.

Una ragione particolare che raccomando è di ottenere una migliore intuizione del modo in cui i semplici passaggi operano interamente deterministicamente, meccanicamente e completamente senza intelligenza o buon senso. Fondamentalmente ci si abitua al modello imperativo di esecuzione nella sua forma più pura e ostinatamente ignorante.

Precisamente quanto è utile sapere la maggior parte di queste cose ora, però, è una domanda difficile.

Una cosa che non imparerai è come giocare bene con una memoria dell'erarchia. Quelle vecchie macchine avevano per lo più un semplice modello di memoria senza livelli di cache e nessuna memoria virtuale. Inoltre non imparerai molto sulla concorrenza: erano certamente modi per gestirli, ma per lo più significava interruzioni. Non dovevi preoccuparti dei mutex, ecc.

A volte, un modello mentale di come queste una volta hanno funzionato, o di come funziona l'assemblatore, può persino essere fuorviante. Ad esempio, pensare a un puntatore C come a un indirizzo può portare a problemi di comportamento non definiti. Un puntatore C viene normalmente implementato come un intero contenente un indirizzo, ma non è garantito che sia strettamente vero. Ad esempio, su alcune piattaforme bizzarre, diversi puntatori possono puntare in diversi spazi di indirizzi. Questo diventa importante quando vuoi fare aritmetica o logica bit a bit con due puntatori.

A meno che tu non abbia una di quelle bizzarre piattaforme, potresti non pensare che ti interessi, ma i compilatori in questi giorni hanno sempre più probabilità di sfruttare gli standard, un comportamento indefinito per l'ottimizzazione.

Quindi un modello mentale dell'architettura di sistema può essere utile, ma è comunque importante codificare le specifiche della lingua., non un modello ipotetico che la tua lingua e la tua piattaforma potrebbero non rispettare.

Infine, molti elementi utili del modello mentale provengono dall'idea di come i compilatori generano il codice, e la generazione di codice per i linguaggi moderni è molto diversa dai compilatori piuttosto banali disponibili in quel momento.

Questo è un mio libro preferito per questo ...

link

Oltre a ciò che riguarda l'analisi e gli AST ecc., copre la generazione del codice per una serie di paradigmi linguistici - imperativo, OOP, funzionale, logico, parallelo e distribuito - e anche per la gestione della memoria. Se vuoi sapere come funzionano le chiamate al metodo polimorfico senza impantanarsi nei dettagli del set di istruzioni della CPU, un libro come questo è tuo amico - e c'è una nuova edizione presto disponibile.

    
risposta data 18.10.2011 - 03:43
fonte
4

Vent'anni fa era importante, ma non così tanto - ci sono molti più livelli di astrazione tra software e hardware moderno.

È utile sapere cose come avere bisogno di più thread per trarre vantaggio da più core o che usare più memoria di quella esistente sul sistema è una cosa brutta, ma oltre a questo non ne hai davvero bisogno a meno che non sia il tuo lavoro scrivi quei livelli di astrazione.

Il resto della tua domanda suggerisce che potresti essere più interessato al compilatore rispetto all'hardware, che è un po 'diverso. Potresti imbatterti in casi in cui è importante, ma questi tendono ad essere banali (la ricorsione infinita non funziona molto bene) o il tipo di casi limite in cui puoi sentirti bene a risolverlo ma probabilmente non incontrerai mai lo stesso problema ancora una volta.

    
risposta data 18.10.2011 - 00:56
fonte
4

Aiuta molto a conoscere e comprendere l'astrazione presentata dall'hardware e un piccolo dell'idea generale su come viene creata quell'illusione - ma cerca di capire veramente come l'hardware moderno veramente funziona è un'enorme quantità di lavoro da cui probabilmente vedrai solo un ritorno minimo.

Se perdonerai un piccolo diversivo: questo mi ricorda qualcosa che ho notato qualche anno fa. Decenni fa (fino alla fine degli anni '70 o giù di lì), la maggior parte della gente pensava che i computer fossero a un passo dal magico - difficilmente influenzati dalle leggi della fisica, capaci di ogni genere di cose che non avevano molto senso e così via. A quel tempo, ho passato un bel po 'di tempo a provare (per lo più senza successo) per convincere la gente che no, non erano magici. Erano macchine abbastanza ordinarie che facevano un numero limitato di cose molto velocemente e in modo affidabile, ma erano estremamente banali

.

Al giorno d'oggi, la visione della maggior parte delle persone sui computer è cambiata. Ora sono abbastanza ordinari, al punto che molte persone molto comuni hanno una comprensione pratica di loro. Per esempio, un po 'di tempo fa mentre stavo cenando, ho visto / ascoltato un cameriere e una cameriera in pausa discutendo su cosa avrebbe dovuto prendere nel suo nuovo computer. Il consiglio che stava dando era del tutto ragionevole e realistico.

La mia vista dei computer è cambiata anche se. Sono passato a Hot Chips, e prima ancora il Microprocessor Forum risaliva alla metà degli anni '90 o giù di lì. Probabilmente saprò di più sull'hardware del microprocessore di almeno il 99% dei programmatori e, sapendo quello che faccio, dirò questo: sono non ordinari più. Loro fanno quasi infrangono le leggi della fisica. Ho fatto un sacco di test di basso livello e posso dirlo con certezza: superare l'illusione creata dalla CPU e mostrare come funziona davvero l'hardware è spesso incredibilmente difficile. Vorrei poter pubblicare un'immagine di uno dei nostri setup con un computer sepolto sotto cavi da non meno di 4 analizzatori logici solo per misurare correttamente l'aspetto one di come la cache funziona su una CPU moderna (per non parlare alcune programmazioni veramente fastidiose per garantire che ciò che abbiamo misurato era esattamente ciò che stava facendo la CPU, e nient'altro).

    
risposta data 18.10.2011 - 01:27
fonte
1

Lingue diverse funzionano a diversi livelli di astrazione dall'hardware. C e C ++ sono di livello molto basso. I linguaggi di scripting, d'altra parte, richiedono di conoscere meno i dettagli sottostanti.

Tuttavia, direi comunque che in tutti i casi, più ne sai, migliore sarà il programmatore. Parte della programmazione è in grado di destreggiarsi tra più livelli di astrazione contemporaneamente.

Se stai programmando in C ++, devi avere una buona conoscenza di come funziona una CPU moderna, almeno a livello di astrazione a cui il compilatore lavora. (Ci sono cose che succedono all'interno della CPU che sono trasparenti anche per il compilatore).

    
risposta data 18.10.2011 - 00:33
fonte
0

Vorrei aggiungere un punto sulla progettazione generale di linguaggi di livello superiore come C.

In generale, penso che sia sicuro dire che tali linguaggi possono essere considerati come l'implementazione di una macchina astratta, ed è proprio così che Dennis Ritchie stesso ha descritto come funziona C e come il particolare design della macchina astratta di C lo abbia reso più portatile linguaggio. In quanto tale, avere una certa comprensione dell'architettura del computer e del funzionamento a livello di macchina può essere estremamente utile anche per capire la macchina astratta di una lingua.

Il documento della DMR Portabilità dei programmi C e il sistema UNIX è il primo che ricordo di aver discusso del modello di macchina (astratto) per C.

Penso che l'articolo di DMR sulla storia e lo sviluppo di C sia anche estremamente utile per mostrare quanto l'hardware reale influenzi la progettazione linguistica, ed è forse anche un esempio di design del linguaggio di programmazione precoce: Lo sviluppo del linguaggio C

    
risposta data 18.11.2012 - 04:27
fonte

Leggi altre domande sui tag