Un po` di storia - Dipartimento di Matematica

Un po' di storia
• Il primo strumento di calcolo utilizzato
nell'antichità da Greci e Romani fu l'abaco.
Un po' di storia
• Le prime macchine calcolatrici (eseguivano
calcoli in maniera automatica) vennero
costruite per risolvere problemi specifici.
• Queste macchine erano di tipo meccanico e si
basavano su un funzionamento simile a quello
degli orologi, con ruote dentate ed ingranaggi.
(par. 6.1)
Un po' di storia
Un po' di storia
• La prima macchina da calcolo è del 1623,
costruita da Wilhelm Schickard (1592-1635,
matematico ed astronomo tedesco): eseguiva
le quattro operazioni.
• Blaise Pascal (1623-1662, francese) costruì
una macchina che eseguiva solo somme e
sottrazioni e che utilizzava le dieci cifre
decimali. (Linguaggio Pascal di Niklaus Wirth
1970).
• John Napier (Neper, 1550-1617, scozzese), il
matematico che inventò i logaritmi, costruì una
macchina (detta “gli ossicini di Nepero”) che
trasformava le moltiplicazioni e le divisioni
in somme e sottrazioni.
• Gottfried Wilhelm Leibnitz (1646-1716,
tedesco) costruì una macchina che eseguiva
anche le moltiplicazioni e le divisioni.
1
Leibnitz ideò il sistema numerico
binario
Un po' di storia
• Charles Babbage (1791-1871, inglese),
ispirandosi ai telai di Joseph-Marie Jacquard
(1752-1834, francese) (schede perforate che
riproducevano disegni ripetuti ciclicamente),
ideò una macchina, detta “alle differenze”, con
la quale si potevano costruire tavole
numeriche e una, detta “analitica”, alla quale
si dovevano fornire schede perforate
contenenti sia i dati da elaborare che le regole
(istruzioni) di calcolo da eseguire.
Un po' di storia
• Georg Scheutz (1785-1873, svedese) si
occupava di tecniche tipografiche e realizzò la
parte stampante della macchina da calcolo;
costruì una macchina simile a quella di
Babbage, che fu acquistata dall'osservatorio
astronomico di Albany (stato di New York)
per costruire delle tavole con cui calcolare la
posizione degli astri.
Un po' di storia
• Per programma (algoritmo) si intende una
sequenza di istruzioni da far eseguire ad una
macchina.
• Chi fu il primo programmatore?
2
Un po' di storia
• Ada Augusta Byron contessa di Lovelace
(1815-1852, inglese), figlia del poeta Lord
Byron. Ada aveva avuto una educazione
matematica e collaborava con matematici
dell'epoca come De Morgan. Ella scrisse una
sequenza di istruzioni (programma) per la
macchina di Babbage, con le quali si potevano
calcolare numeri di Bernoulli.
Linguaggio
Ada
concorrente.
(1979):
programmazione
Nuove invenzioni alla fine del
secolo diciannovesimo
• La macchina da scrivere.
• Il comptometro, dello statunitense D. E. Felt: prima
calcolatrice da tavolo provvista di tasti per introdurre
i dati.
• La macchina a schede perforate, dello statunitense
Hermann Hollerit:
• usava l'elettricità, venne utilizzata in Canada nel 1890 per il
censimento.
• Hollerit nel 1896 fondò la Tabulating Machine Company
che nel 1924 divenne la IBM (International Business
Machines).
Il primo calcolatore
Il primo calcolatore
• Konrad Zuse, tedesco, costruì nel 1938 una
calcolatrice meccanica, chiamata Z1.
• Successivamente nel 1941 costruì lo Z3, un
calcolatore elettromeccanico considerato il
primo calcolatore.
– Zuse utilizzò il relè che poteva avere solo due
posizioni, pertanto abbandonò il sistema decimale
(ruote dentate potevano essere numerate) e passò
al sistema binario.
3
Il primo calcolatore
• Nel 1944 Howard Aiken, dell'università di
Harvard, costruì (indipendentemente) il suo
primo calcolatore elettromeccanico Mark I.
– Mark I usava il sistema decimale e le schede
perforate: aveva l'aspetto di un armadio, lungo 16
metri. Eseguiva 3 addizioni in un secondo,
impiegava 6 secondi per una moltiplicazione e 12
per una divisione.
– Modelli successivi: Mark II e Mark IV.
Calcolatori moderni
Calcolatori moderni
I generazione (dalla metà degli
anni '40 alla metà degli anni '50)
• A differenza delle prime macchine, i
calcolatori
moderni
sono
macchine
universali, perché realizzano applicazioni
diverse.
• E' l'epoca delle valvole termoioniche.
• ENIAC (Electronic Numerical Integrator
And Computer, integratore numerico e
calcolatore elettronico), progettato presso
l'università della Pennsylvania (1945-47).
• Con l'evoluzione della tecnologia i calcolatori
sono così cambiati che si distinguono
generazioni successive di macchine.
• Occupava una grande stanza ed era costituito da molti
armadi con circa 18000 valvole, parecchie delle quali si
bruciavano ogni giorno e dovevano essere sostituite;
veniva programmato collegando cavi su appositi pannelli,
simili a quelli dei centralini telefonici, ogni specifico
problema richiedeva un diverso collegamento dei cavi;
eseguiva 5000 addizioni al secondo.
4
L’ENIAC
I generazione (dalla metà degli
anni '40 alla metà degli anni '50)
• L'ungherese J. Von Neumann progettò nel
1946 la macchina EDVAC e poi lo IAS.
• IAS: le componenti erano organizzate secondo una
architettura presente ancora oggi sui calcolatori:
architettura di von Neumann.
II generazione (dalla metà degli anni
'50 alla prima metà degli anni '60)
• E' l'epoca dei transistor, molto più piccoli e
meno costosi delle valvole termoioniche.
• In questo periodo si ha lo sviluppo del
software: si costruiscono i primi linguaggi ad
alto livello e i primi sistemi operativi.
III generazione (fino ai primi anni
'70)
• E' l'epoca dei circuiti integrati: una
componente unica contiene centinaia di
transistor.
• Si passa ai circuiti integrati su larga scala: LSI
(Large Scale Integration) con migliaia di
transistor.
• Nel 1969 M. E. Hoff, ingegnere della Intel,
riuscì a ridurre le dimensioni della CPU fino a
qualche centimetro, ottenendo i cosiddetti chip
(microprocessori).
5
IV generazione (attuale)
• E' l'epoca dei circuiti integrati su scala molto
larga (VLSI: Very Large Scale Integration) e
dei circuiti integrati su scala ultra-larga (ULSI:
Ultra Large Scale Integration) contenenti
milioni di transistor.
V generazione (attuale)
• Tecnologia WSI (Wafer Scale Integration) con
dispositivi ancora più piccoli e con decine di
milioni di dispositivi su un unico chip (wafer
perché sono costituiti da più strati).
• Il chip del Pentium 4 contiene 50 milioni di
transistor.
• Calcolatori con architetture parallele.
I Chip
• I chip (pezzetto) sono sottili lamine di silicio
(dopo l'ossigeno è l'elemento più diffuso) che
contengono milioni di interruttori che
realizzano i due stati acceso/spento e che sono
collegati da tracce di alluminio come dei
sottilissimi fili dello spessore di mezzo micron
(1µ = 10-9 m., un capello è dello spessore di
100 µ).
• Case costruttrici: Intel, Motorola, Apple,
Digital, Sun, ...
I Chip
• I chip sono piccoli, costano poco, sono molto
potenti e facilmente costruibili.
• Costruzione di un chip:
• progettazione del disegno di tutti i collegamenti
tra i milioni di transistor;
• costruzione di maschere: le maschere sono
lamine di quarzo sulle quali viene inciso il disegno
(una maschera per ogni strato del chip), e che
viene fotografato su una fetta di silicio;
(par. 6.2)
6
I Chip
• controllo di ogni fetta: vengono controllati
centinaia di chip e le parti difettose vengono
marcate;
• rivestimento: le fette vengono tagliate in pezzetti
(chip) che poi vengono rivestiti (il rivestimento
serve sia per protezione che per costruire dei
collegamenti con le altre componenti) e alloggiati
in un contenitori di plastica o ceramica .
Lo sviluppo teorico
Lo sviluppo teorico
La teoria della calcolabilità
• Con l'evoluzione tecnologica delle macchine
da calcolo si ha parallelamente un aumento dei
problemi che si vogliono far risolvere ai
calcolatori: di molti problemi si cerca la
soluzione per via numerica (integrali, sistemi,
equazioni differenziali, ...).
• Qualsiasi problema può essere risolto
tramite un programma?
• Il matematico e logico Alan Turing (19121954, inglese), inventore della teoria della
calcolabilità, definì il concetto di funzione
calcolabile e ideò un modello astratto di
calcolatore (Macchina di Turing) nel quale la
computazione è rappresentata da una sequenza
di trasformazioni di stato.
• Egli scoprì che esistono problemi indecidibili:
problemi per i quali non esiste un algoritmo
in grado di risolverli.
7
Computer e Programma
• Un computer è una macchina che
Computer e
Programma
– memorizza dati
(numeri, parole, immagini,
suoni...)
– interagisce con dispositivi (schermo, tastiera,
mouse...)
– esegue programmi
• Un programma è una sequenza di istruzioni
che il computer esegue e di decisioni che il
computer prende per svolgere una certa
attività.
Programmi e istruzioni
Cos’è la programmazione?
• Nonostante i programmi siano molto sofisticati
e svolgano funzioni molto complesse, le
istruzioni di cui sono composti sono molto
elementari, ad esempio
• Un programma descrive al computer, in
dettaglio, la sequenza dei passi necessari per
svolgere un particolare compito.
• L'attività di progettare e realizzare un
programma è detta programmazione.
• Usare un computer non richiede alcuna
attività di programmazione (così come per
guidare una automobile non è necessario
essere un meccanico).
• Un informatico professionista solitamente
svolge una intensa attività di programmazione.
•
•
•
•
estrarre un numero da una posizione della memoria
sommare due numeri
inviare la lettera A alla stampante
se un dato è negativo, proseguire l'esecuzione del
programma da una certa istruzione anziché dalla
successiva (decisione).
8
Problemi
Problemi da
risolvere
• Quale tipo di problemi è possibile risolvere
con un computer?
• Dato un insieme di fotografie di paesaggi, qual è il
paesaggio più rilassante?
• Avendo depositato ventimila euro in un conto
bancario che produce il 2% di interessi all’anno,
capitalizzati annualmente, quanti anni occorrono
affinché il saldo del conto arrivi al doppio della
cifra iniziale?
• Il primo problema non può essere risolto dal
computer. Perché?
Problemi
• Il primo problema non può essere risolto dal
computer perché non esiste una definizione di
paesaggio rilassante che possa essere usata
per confrontare in modo univoco due paesaggi
diversi.
• Un computer può risolvere soltanto problemi che
potrebbero essere risolti anche manualmente: è
solo molto più veloce, non si annoia, non fa errori.
Problemi
• I problemi da risolvere sono di varia natura:
– mettere in ordine alfabetico dei nomi di persone;
– trovare gli zeri di una funzione f(x);
– contare quante volte una parola compare all'interno
di un testo;
– gestire acquisti e prestiti dei libri di una biblioteca.
• Il secondo problema è certamente risolvibile
manualmente, facendo un po’ di calcoli...
9
Problemi e algoritmi
• Indipendentemente da chi sarà l'esecutore
(l'uomo o la macchina) la prima cosa da fare è:
trovare l'algoritmo risolutivo, ossia la
sequenza di operazioni che permette di
passare dai dati ai risultati.
Algoritmi
•
Un algoritmo (Al Kowarizmi, matematico
persiano del IX secolo d. C.) è un
procedimento di soluzione che gode delle
seguenti proprietà:
1. è un insieme di operazioni eseguibili;
2. esiste una prima operazione;
3. dopo ogni operazione è individuata la
successiva;
4. esiste un'ultima operazione.
Algoritmi
Algoritmi: operazione eseguibile
• non è ambigua, è univocamente interpretabile
da un esecutore (uomo o macchina):
• le operazioni tra numeri hanno un simbolo non
ambiguo:
• 2*3 (prodotto)
• 2p3 è ambigua
2+3 (somma)
p: per o più
• è effettiva, l'esecutore deve poterla svolgere in
un tempo finito:
• somma di due numeri interi: sì
• calcolo di un limite: no (concetto di infinito)
(par.1.2)
10
Algoritmi
Algoritmi
• Le proprietà 2. e 4. rappresentano la finitezza:
un algoritmo deve terminare in un tempo
finito.
• La proprietà 3. dice che l'algoritmo è
deterministico: ad ogni passo è univocamente
individuato il passo successivo.
• Si possono ideare algoritmi non deterministici:
• ad ogni passo c'è più di una scelta e
l'algoritmo individua tra le scelte quella che
porterà alla soluzione.
• simulazione: si può pensare ad una
esecuzione contemporanea delle scelte.
Algoritmi
Algoritmi
•
Problema: Avendo depositato ventimila euro
in un conto bancario che produce il 2% di
interessi all’anno, capitalizzati annualmente,
quanti anni occorrono affinché il saldo del
conto arrivi al doppio della cifra iniziale?
Algoritmo:
1. L'anno attuale è 0; il saldo attuale è 20000 euro
2. Ripetere i passi 3. e 4. finché il saldo attuale è
minore di 40000, quindi passare al passo 5
3. Aggiungere 1 al valore dell'anno
4. Il nuovo saldo attuale è il valore del saldo attuale
moltiplicato per 1.02 (1 + 2/100)
5. Il risultato è il valore dell'anno attuale
11
Algoritmi
Algoritmi
• Ogni operazione è eseguibile: somme e
prodotti (effettive e non ambigue)
• I valori delle variabili (anno, saldo, interesse)
sono effettivi:
• Se vogliamo fare eseguire l'algoritmo da un
calcolatore, dobbiamo trasformare la sequenza
di istruzioni in una sequenza scritta in un
linguaggio comprensibile alla macchina:
programma, codice.
• I primi programmi erano scritti in linguaggio
macchina (o codice binario, ossia una
sequenza di simboli 0 e 1).
• se l'interesse dipendesse da parametri noti solo nel
futuro non calcolabili a priori non potremmo
eseguire l'aggiornamento del saldo.
• E' finito perché il 2% di 20000 euro sono 400
euro e quindi al più dopo cinquanta anni si
raggiunge il saldo desiderato: il ciclo termina.
Algoritmo → Programma
Algoritmo →Programma
• Nel corso degli anni si sono sviluppati vari
linguaggi; si è passati da quelli cosiddetti a
• basso livello, perché più vicini alla
macchina, come Assembler
• a quelli detti ad
• alto livello, perché più vicini all’uomo
come Pascal, C, Java.
12
Algoritmo → Programma
Analisi
• La risoluzione avviene in due passi:
• Analisi: problema → algoritmo
• Codifica: algoritmo → programma (codice)
• Per far eseguire il programma al calcolatore
occorre imparare ad usare quei programmi che
ne gestiscono le risorse (implementazione):
• editor di testo, compilatore, esecutore,
funzioni del sistema operativo; test di
funzionamento.
• Occorre inventare il procedimento di soluzione
che sarà indipendente (o quasi) dal linguaggio
di programmazione; si distinguono due fasi:
• definizione del problema: individuare la struttura
dati più idonea, risolvere un problema generale;
• progettazione del programma: individuare le
istruzioni e l'ordine di esecuzione; si procede dal
problema generale e si scende nei particolari; si
può utilizzare un linguaggio di pseudocodifica.
(par. 1.3)
Codifica
Programma
• Occorre trasformare le istruzioni in frasi
comprensibili al calcolatore; si deve imparare
un linguaggio di programmazione.
• Noi studieremo il linguaggio C++.
• Un buon programma deve essere facilmente
utilizzato da altri, deve durare nel tempo, deve
essere facilmente aggiornabile.
• Come sistema operativo utilizzeremo Linux.
• Verifica:
• casi di prova e test di funzionamento
• gestione di casi eccezionali
• controllo della terminazione.
• Documentazione:
• inserire delle frasi di commento che spieghino
“cosa fa” il programma.
13
Risorse di un calcolatore
• Risorse hardware:
Risorse di un
calcolatore
• componenti fisiche
• Risorse software:
• programmi di gestione e applicativi
• Risorse firmware:
• componenti hardware
specifiche funzioni
preprogrammate
per
(par. 6.4)
Risorse hardware
Risorse hardware
• Unità centrale: l'unità di elaborazione
centrale (CPU) e la memoria centrale o
primaria.
• Memorie secondarie o ausiliarie o di massa.
• Dispositivi di ingresso/uscita.
• Connessioni e supporti: linee di collegamento
(bus), scheda madre.
14
L'architettura di von Neumann
• Ideata da Janos' (John) von Neumann:
•L'elaboratore è dotato di una memoria
nella quale vengono registrati sia i dati che
i programmi da eseguire.
•Il calcolatore diventa una “macchina
universale”, perché riceve in ingresso
(input) i dati e il programma e restituisce
in
uscita
(output)
i
risultati
(l’elaborazione dei dati eseguita dal
programma).
L'architettura di von Neumann
CA
CC
C
I
M
O
R
CA + CC
M
I
O
R
= unità centrale di elaborazione
= memoria centrale
= dispositivi di ingresso
= dispositivi di uscita
= dispositivi di memoria ausiliaria
L'architettura di von Neumann
• La grande maggioranza degli elaboratori
odierni ha una architettura che può essere (più
o meno facilmente) ricondotta al modello di
von Neumann:
• le eccezioni più importanti sono alcune
macchine ad elaborazione parallela.
• Il modello è importante perché semplificò
l’architettura
dell’hardware
rendendolo
omogeneo.
La Memoria
primaria
15
La Memoria primaria
La memoria primaria si compone di due parti:
• ROM (Read Only Memory)
• RAM (Random Access Memory)
La memoria ROM
• È una memoria a sola lettura:
• costituita da celle nelle quali non è possibile
immagazzinare nuovi dati, ma dalle quali si possono
estrarre informazioni (lettura).
• È ad accesso diretto (casuale)
• Essa mantiene il suo contenuto a macchina spenta e
contiene i programmi eseguiti all'accensione del
sistema:
• test di funzionamento, caricamento del software di base,
BIOS (Basic Input/Output System)
• Tali informazioni (firmware) vengono inserite dalla
ditta costruttrice.
La memoria RAM
La memoria
• È il dispositivo nel quale si possono immettere,
conservare, estrarre le informazioni da elaborare: il
programma e i dati
• Il byte è l'unità di misura della capacità della
memoria
• chip di memoria realizzati con la stessa tecnologia (al
silicio) utilizzata per la CPU.
• 1Kbyte (kilobyte):
• 1Mbyte (megabyte):
• L'informazione elementare (unità minima di
informazione) si chiama bit (binary digit) o cifra
binaria.
• Rappresenta i due stati di un circuito “aperto” e “chiuso”,
convenzionalmente detti 0 e 1, o anche “falso” e “vero”.
• 1Gbyte (gigabyte):
• 1Tbyte (terabyte):
210 byte = 1024 byte ~
103 byte
220 byte = 1 048 576 byte ~
106 byte
230 byte =1 073 741 824 byte ~
109 byte
240 byte ~ 1012 byte (mille miliardi)
• RAM 512 Mbyte …. vari Giga …
16
La memoria RAM
• La memoria è organizzata a gruppi di bit
(solitamente 8) chiamati byte.
• La memoria è costituita da un numero finito m
di celle, o locazioni di memoria, tutte della
stessa dimensione.
• Ogni cella è composta da un numero n predefinito
di bit
• n = 8, 16, 32, 64 quindi 1, 2, 4, 8 byte.
• Il contenuto di una cella di memoria si chiama
parola (word): è un numero binario fisicamente
memorizzato all'interno di essa.
La memoria RAM
Ogni cella è individuata da un indirizzo.
L’indirizzo di memoria è un numero naturale
progressivo (0, ..., m-1) che individua ogni cella in
maniera univoca all’interno della memoria stessa.
Lo spazio di indirizzamento è l'insieme di tutti gli
indirizzi possibili delle celle di memoria:
• dipende dal numero di bit destinati a rappresentare un
indirizzo;
• ogni bit può assumere due valori, quindi con k bit si
possono rappresentare 2k indirizzi diversi, k=16, 32, 64.
La memoria RAM
La memoria RAM
• Lo spazio di memoria è la quantità di
memoria disponibile. Dipende dal numero di
indirizzi e dalla grandezza delle celle.
• Accedere ad un dato significa selezionare
mediante l'indirizzo la cella in cui è
memorizzato e prelevarne il valore (lettura).
• Memorizzare un dato significa selezionare
mediante l'indirizzo la cella in cui si intende
introdurlo ed introdurre il dato (scrittura).
• Si chiama tempo di accesso il tempo che
intercorre tra l'istante in cui si richiede
l'informazione e l'istante in cui tale
informazione è disponibile.
• Si chiama ciclo di memoria il tempo minimo
richiesto tra due accessi consecutivi.
• Viene misurato in nanosecondi (ns = 10-9 secondi);
si hanno cicli di memoria anche inferiori ai 30 ns.
17
La memoria RAM
• È una memoria ad accesso diretto (casuale)
• il tempo di accesso è lo stesso per ogni indirizzo
• È costituita da celle nelle quali è possibile
estrarre e registrare nuove informazioni
(lettura e scrittura).
• È una memoria volatile
• perde il suo contenuto quando la macchina viene spenta.
• Nella RAM si scrivono le istruzioni che
compongono i programmi e i dati.
• La RAM è veloce e costosa.
Altre memorie
• Memoria cache
• area di memoria ad accesso veloce, localizzata tra
CPU e RAM, utilizzata per contenere dati e
istruzioni di prossimo utilizzo da parte del
processore (frigorifero).
• Il caricamento dei dati è sequenziale
• Memoria buffer
• area di memoria temporanea utilizzata nei
collegamenti tra dispositivi di diversa velocità (tra
CPU e tastiera, video, stampante):
• salvare gli ultimi comandi usati
• operazioni di copia/incolla
Altre memorie
• La quantità di RAM limita le dimensioni dei
programmi e dei dati che sono direttamente
accessibili.
• Memorie virtuali:
• se lo spazio di indirizzamento lo consente, si riesce
a sfruttare anche lo spazio su disco (hard disk) in
modo che i trasferimenti di informazioni risultino
invisibili all'utente. Il sistema operativo vi
memorizza parte dei dati e dei programmi non in
uso, e quando questi sono necessari li trasferisce
nella RAM.
L'unità centrale di elaborazione
CPU
• La CPU (Central Processing Unit) esegue le
istruzioni del programma, legge e scrive le
informazioni nella memoria centrale, richiede
servizi alle apparecchiature periferiche, è
costituta da uno o più chip.
• È composta da:
• ALU: Arithmetic Logic Unit
• Unità di controllo
• registri
18
ALU: unità aritmetico-logica
Unità di controllo
• La ALU (Arithmetic Logic Unit) è la parte
operativa: esegue le operazioni
• Accede solo alle informazioni contenute nella
memoria centrale ed ha il compito di gestire
la successione delle operazioni da svolgere:
• aritmetiche
•
addizione, sottrazione, moltiplicazione e divisione
• logiche
•
confronti di valori
• utilizza i valori depositati in appositi registri (celle di
memoria ad accesso veloce per la memorizzazione
temporanea dei dati).
Principali registri della CPU
• Contatore di programma (PC: Program Counter)
– contiene l'indirizzo di memoria
istruzione da caricare ed eseguire
della
successiva
• Registro istruzioni (IR: Instruction Register)
– contiene l'istruzione che deve essere interpretata ed
eseguita
• Registro dati
– Contiene dati, risultati intermedi
• Registro di stato
• reperire dalla memoria le istruzioni (caricamento)
• interpretarle (decodifica)
• farle eseguire: caricare gli operandi, eseguire
l'istruzione, memorizzare il risultato (esecuzione).
Funzionamento della CPU
• Il funzionamento è ciclico:
• Ciclo fetch-decode-execute
• fetch: caricamento dalla memoria dell'istruzione da
eseguire e sua memorizzazione nel registro
istruzioni; incremento di una unità del contatore
di programma (istruzioni eseguite in sequenza)
• decode: decodifica dell'istruzione da eseguire
• execute: esecuzione dell'istruzione
– Contiene segnalatori che indicano condizioni particolari
• Overflow, risultato 0 o negativo
19
Clock
Coprocessore
• È un segnale che viene trasmesso ai vari
circuiti per sincronizzarne il funzionamento:
• Accanto alla CPU esistono altri processori
con funzioni specifiche:
• l'intervallo di tempo tra due impulsi successivi si
chiama periodo di clock e viene misurato in
Megahertz (MHz milioni di cicli al secondo),
Gigahertz (miliardi di cicli al secondo)
• si può dire che è la frequenza con cui il
processore esegue le singole operazioni
elementari
• maggiore è la frequenza, più veloce è il processore
all'interno della stessa famiglia.
• processori diversi posso elaborare lo stesso numero di
operazioni con periodi di clock diversi.
• Coprocessore matematico che esegue i calcoli in
virgola mobile, moltiplicazioni tra interi, …
• Coprocessore grafico che gestisce le informazioni
registrate nella memoria e le trasforma in grafica
sullo schermo.
I bus
I bus
• I bus sono linee di collegamento tra la CPU e
la memoria centrale (bus interni) e le
periferiche (bus esterni)
• I bus sostituiscono l'insieme (complesso) dei
collegamenti reciproci tra tutte le singole
componenti.
• I bus trasportano vari tipi di informazioni, la
velocità del “traffico smaltito” dipende dal numero
di bit (32, 64) che i bus riescono a trasportare
simultaneamente.
• Il bus è in realtà costituito da tre bus distinti:
• bus dei dati
• bus degli indirizzi (destinatario, mittente)
• bus dei segnali di controllo
• Sul bus dei dati viaggiano dati da e verso la
CPU.
• Sugli altri bus viaggiano indirizzi e segnali di
controllo che provengono soltanto dalla CPU.
CPU
Memoria
Memoria
principale
secondaria
Dispositivi
di Input e
di Output
Bus
20
Le memorie secondarie
Le memorie
secondarie
• Sono dette anche memorie di massa o
ausiliarie.
• Hanno una funzione ed una realizzazione
hardware diversa da quelle della memoria
primaria
• permettono di mantenere le informazioni anche a
macchina spenta
• sono meno costose
• l'accesso è più lento
• in alcune dipende dalla posizione del dato
Le memorie secondarie
• Unità a disco
• Solitamente ad accesso diretto (Gbyte, Tbyte)
• Disco rigido o hard disk
• Disco flessibile o floppy disk
• Dischi ottici
• Nastri magnetici
• Ad accesso sequenziale: il tempo di accesso
dipende dalla posizione del dato
Hard disk
• Il disco rigido è composto da una pila di piatti
rotanti rivestiti di un materiale magnetico.
Ogni piatto è organizzato in tracce circolari
concentriche, ciascuna traccia è divisa in
settori (inizializzazione o formattazione). La
testina di lettura/scrittura si sposta in senso
radiale
individuando
univocamente
la
posizione.
• Hanno elevata capacità, ma sono lenti; si utilizzano per
copie di sicurezza. Sono a tecnologia magnetica.
21
Hard disk
• è contenuto in una scatola sigillata per
proteggerlo dalla polvere
• programmi e dati risiedono sul disco rigido
e vengono caricati nella RAM quando
necessario, per poi tornarvi aggiornati se e
quando necessario.
Altre memorie secondarie
• Nei dischetti lo strato magnetico è applicato
su un supporto flessibile.
• Nei dischi ottici la lettura avviene tramite un
raggio laser ed un rilevatore del passaggio
della luce (alcuni sono sequenziali con tracce
a spirale, altri ad accesso diretto):
• CD-ROM: Compact Disk Read Only Memory
• usato per distribuire programmi o informazioni
Altre memorie secondarie
• CD-R (Compact Disk Recordable)
• può essere scritto dall'utente una sola volta
• CD-RW possono essere scritti più volte
• DVD (Digital Video Disk, Digital Versatile Disk)
• enorme capacità di memorizzazione
• “chiavette” USB (o penne) in sostituzione del
floppy
• capacità superiore ai floppy (Gbyte).
Principali dispositivi di ingresso
•
•
•
•
•
•
•
Tastiera
Mouse
Trackball
Joystick
Microfono
Scanner
Penna luminosa
22
Principali dispositivi per l'uscita
•
•
•
•
Video (schermo)
Stampante
Plotter
Altoparlanti
La scheda madre
• La scheda madre (mother-board) situata
all'interno di un Personal Computer contiene la
memoria primaria, la CPU, i bus, gli
alloggiamenti (slot) di espansione, le porte per
il controllo delle periferiche.
La scheda madre
La scheda madre di un PC
CPU
slot
Rappresentazione
delle informazioni
RAM
23
Rappresentazione delle
informazioni
• L’informatica si occupa di rappresentare ed elaborare
informazioni:
• numeri
• caratteri
• audio
• immagini
• video
Rappresentazione
dei caratteri
I caratteri
I caratteri
• I caratteri appartenenti ad un alfabeto
vengono codificati (cioè “rappresentati”)
mediante sequenze di bit: una diversa
sequenza per ciascun diverso carattere.
• Uno dei codici più noti e usati è il codice
ASCII (American Standard Code for
Information Interchange):
• Dato che l’unità elementare di informazione
nei calcolatori è il byte (= 8 bit), si è passati ad
usare, quasi sempre, il codice ASCII esteso,
che usa una sequenza di 8 bit per ciascun
carattere degli alfabeti occidentali:
• usa una sequenza di 7 bit per ciascun carattere: ci
sono 128 (=27) sequenze diverse, utilizzate anche
per lettere, segni di punteggiatura, cifre decimali,
ecc.
• ci sono 256 (=28) sequenze diverse, utilizzate
anche per vocali accentate e altre lettere speciali
(es. ß tedesca, ç francese)
• le sequenze con la prima cifra uguale a zero
coincidono con il codice ASCII
(par. 6.9)
24
I caratteri
I caratteri (codice Unicode)
• I primi 32 caratteri del codice ASCII (con codice da
0 a 31) sono caratteri di controllo:
• Per rappresentare i segni grafici utilizzati da
tutti gli alfabeti del mondo servono molti più
simboli diversi.
•
•
•
9 tabulatore
10 nuova riga
13 invio
’\t’
’\n’
’\r’
• I caratteri da 32 a 127 sono caratteri stampabili:
• 32 spazio
’’
• da 48 a 57 caratteri numerici, le cifre decimali ’0’, ’1’…
• da 65 a 90, da 97 a 122 caratteri alfabetici (maiuscoli e
minuscoli)
• da 33 a 47, da 58 a 64, da 91 a 96, da 123 a 127 caratteri
di interpunzione.
• Codifica Unicode
http://www.unicode.org
• usa una sequenza di 16 bit
segno grafico:
per ciascun
• ci sono 65536 (= 216) sequenze diverse
• le sequenze con le prime otto cifre uguali a zero
coincidono con il codice ASCII esteso.
I caratteri (codice Unicode)
Risorse software
25
Risorse software
Software di base
• Con la parola software si intende in generale
un insieme di programmi.
• Si distinguono però i programmi fatti dagli
utenti dai programmi propri del calcolatore e
che gli utenti utilizzano:
• Il software di base è un insieme di programmi
che permettono il funzionamento del
calcolatore e il suo utilizzo da parte di utenti
esterni.
• Esso interagisce direttamente con l’hardware
nascondendo all’utente la struttura fisica della
macchina.
• software di base
• software applicativo
• pacchetti di programmi che risolvono specifici problemi
(“libreria”, “library - biblioteca”).
(par. 6.7)
Software di base
• Le principali componenti sono:
• Sistema operativo
• programmi per il funzionamento del calcolatore; il S.O.
è strettamente legato all’hardware
• Interfaccia utente
• permette la comunicazione con il sistema operativo:
comandi da tastiera o da menu (grafica)
Linguaggi di
programmazione
• Software di comunicazione
• comunicazione tra calcolatori: reti locali o mondiali.
26
Linguaggi di programmazione
Linguaggi di programmazione
• I linguaggi di programmazione sono quei
linguaggi in cui si devono esprimere le
istruzioni che si vogliono elaborare.
• Nei linguaggi di programmazione si
distinguono dei livelli e delle generazioni:
• generazioni: le varie generazioni si distinguono in
base ai concetti che sono stati successivamente
introdotti
• basso livello:
• I generazione: linguaggio macchina
• II generazione: linguaggi tipo Assembler
• alto livello
• III generazione: linguaggi procedurali (imperativi)
Fortran, Pascal, C, Java, …
• IV generazione: linguaggi logici (Prolog) e
funzionali (Lisp)
• livello
basso livello
“vicini” alla macchina
alto livello
“vicini” all’uomo
(par. 4.1)
Linguaggi di programmazione
Linguaggi di programmazione
• I linguaggi procedurali sono linguaggi in cui
si individuano gruppi di istruzioni
(procedure) che risolvono un problema
specifico; sono detti anche imperativi perché
le
istruzioni
eseguono
comandi
di
assegnazione di valori nella memoria.
• Il passaggio dai linguaggi a basso livello a
quelli ad alto livello si ha con l’introduzione
del concetto di variabile: in tale modo si ha
l’indipendenza dalla locazione di memoria.
• Successivamente sono stati introdotti i concetti
di tipo di dato e di tipo di dato astratto
(linguaggi a oggetti).
• Nei linguaggi ad alto livello si hanno le
strutture di controllo che permettono di
regolare il flusso delle operazioni da eseguire.
27
Le istruzioni macchina
Programmazione in
linguaggio macchina
• Le istruzioni elementari eseguite da un
computer (cioè dalla sua CPU) si chiamano
istruzioni macchina.
• L’insieme di istruzioni macchina (instruction
set) è specifico di una particolare CPU (CPU
diverse hanno un diverso insieme di
istruzioni).
Le istruzioni macchina
Le istruzioni macchina
• I primi programmi erano scritti in linguaggio
macchina e quindi un programmatore doveva
conoscere tutti i codici numerici delle
istruzioni macchina, oltre alle istruzioni che
costituivano l’algoritmo risolutivo.
• Nel linguaggio macchina le istruzioni sono
scritte in codice binario (sequenze di 0 e 1);
sono pertanto difficili da scrivere e poco
leggibili.
• Esempio.
Supponiamo di voler confrontare due numeri,
il primo è memorizzato in una variabile di
nome a, il secondo è il valore costante 100, e
vogliamo esprimere questa situazione:
se a > 100
allora stampa “ERRORE”
28
Le istruzioni macchina
Le istruzioni macchina
• Le istruzioni macchina dovranno rappresentare
una sequenza di operazioni di questo tipo:
• In tutte le CPU, le istruzioni macchina si
possono suddividere nelle seguenti categorie
(i nomi delle istruzioni sono solo degli esempi)
• carica in un registro il valore contenuto nella
posizione di memoria 40 (numero naturale)
• nel linguaggio macchina non esiste il concetto di
variabile, ma solo la locazione di memoria individuata
da un indirizzo
• carica in un altro registro il valore 100
• se il primo valore è maggiore del secondo,
prosegui con l’istruzione contenuta nella posizione
di memoria 240
• trasferimento dati, tra i registri e la memoria
principale
• LOAD (verso un registro), STORE (verso la
memoria)
• operazioni aritmetiche e logiche, eseguite dalla
ALU
• aritmetiche: ADD, SUB, MUL, DIV
• logiche: AND, OR, NOT
Le istruzioni macchina
• salti, per alterare il flusso di esecuzione
sequenziale (viene modificato il Program Counter)
• incondizionato (JUMP): salta in ogni caso
• condizionato: salta solo se un certo valore è zero
(JZ) o se è maggiore di zero (JGZ)
Linguaggio
Assembler
29
Linguaggio Assembler
Assemblatore
• Si utilizzano dei nomi simbolici per
rappresentare le operazioni da eseguire e per
rappresentare le locazioni di memoria:
• Utilizzando l’assemblatore, il programmatore
scrive il programma mediante dei nomi
abbreviati (codici mnemonici) per le
istruzioni macchina: il programma diventa più
facile da scrivere e da leggere .
• Il programma assemblatore si occupa poi di
tradurre il programma in configurazioni di
bit.
• Tali linguaggi con codici mnemonici si dicono
linguaggi assembly (uno diverso per ogni
CPU).
istruzioni assembler istruzioni macchina
corrispondenza
biunivoca
I linguaggi assembly
• Problema: occorrono molte istruzioni per
eseguire anche le operazioni più semplici
• Problema: la sequenza di istruzioni di uno
stesso programma cambia al cambiare della
CPU
• è molto costoso scrivere programmi che possano
funzionare su diverse CPU, perché praticamente
bisogna riscriverli completamente
Linguaggi
di programmazione
ad alto livello
30
Linguaggi ad alto livello
Linguaggi ad alto livello
• Negli anni ‘50 furono inventati i primi
linguaggi di programmazione ad alto livello
• Il programmatore esprime la sequenza di
operazioni da compiere, senza scendere al
livello di dettaglio delle istruzioni macchina.
• FORTRAN (1956): primo “vero” linguaggio
• BASIC, COBOL
• Anni ‘60 e ‘70: programmazione strutturata
• Pascal (Niklaus Wirth, 1968)
• C (Brian Kernigham e Dennis Ritchie, 1970-75)
• Anni ‘80 e ‘90, programmazione orientata agli
oggetti
• C++ (Bjarne Stroustrup)
• Java (James Gosling e Patrick Naughton, 1991)
(par. 6.7.5)
• C++:
if(a>100)
cout<<"Errore\n";
• Java:
if(a>100)
System.out.println("Errore");
Linguaggi ad alto livello
• Pascal:
if a>100 then
writeln ('Errore');
• Fortan
if(a.gt.100) then
write(6,*) 'Errore'
Traduzione in
linguaggio macchina
endif
Nel Fortan l’istruzione deve essere scritta su righe diverse.
31
Traduzione in linguaggio
macchina
• Le istruzioni scritte in un linguaggio ad alto
livello non sono comprensibili alla macchina;
occorre pertanto tradurle.
• Si hanno due tipi di traduttori:
• interpreti
• compilatori
(par. 6.7)
Compilatore
• Sia X un linguaggio.
Un compilatore per X è un programma che
riceve in ingresso un programma scritto in X,
lo traduce in una sequenza di istruzioni scritte
in linguaggio macchina (codice oggetto) ed
esegue dei controlli:
• analisi lessicale, sintattica, semantica.
Interprete
• L’interprete traduce ogni istruzione del
programma sorgente e la esegue (Basic, Perl).
• Gli interpreti sono programmi semplici.
• Un programma scritto in un linguaggio con
interprete ha una gestione poco efficiente
perché ogni volta che si esegue il programma,
le
istruzioni
devono
essere
tradotte
nuovamente (esempio: errori di scrittura,
esecuzione su nuovi dati).
Compilatore
• Analisi lessicale:
• Si verifica che le parole del programma siano
scritte correttamente secondo le regole del
linguaggio.
• Analisi sintattica:
• Si verifica che le frasi del linguaggio siano scritte
correttamente.
• Analisi semantica:
• Si verifica che la frase abbia significato (coerenza).
32
Compilatore e linker
Portabilità ed efficienza
• Se la compilazione ha avuto buon esito, un
altro programma (linker) prende il codice
oggetto, esegue gli agganci necessari (con
moduli di libreria e moduli oggetto scritti
dall’utente) e produce un “codice eseguibile”.
• Il codice eseguibile (comprensibile alla
macchina) viene elaborato (programma in
esecuzione).
• I linguaggi intrepretati sono portabili a livello
di codice sorgente: possono essere eseguiti su
macchine con diverse CPU. Sono poco
efficienti per l’implementazione.
• I linguaggi compilati sono portabili a livello di
codice sorgente, ma non a livello di codice
macchina, che dipende dalla CPU. Sono
efficienti perché permettono di correggere gli
errori prima dell’esecuzione e la traduzione è
fatta una sola volta per prove diverse.
• In alcuni linguaggi compilazione e link sono in un
solo passo.
Le fasi della programmazione
Le fasi della
programmazione
• L’attività di programmazione si esegue in tre
fasi:
• scrittura del programma (codice sorgente)
• compilazione del codice sorgente e
creazione del codice eseguibile (codice
macchina)
• esecuzione del programma.
33
Le fasi della programmazione
Le fasi della programmazione
• Per scrivere il codice sorgente si usa un editor
di testo, salvando (memorizzando) il codice in
un file: ad esempio in un file di nome
primo.c
• Per compilare, richiamiamo il compilatore C++
scrivendo il comando
• Solitamente si hanno a disposizione più editor
richiamabili o tramite icona, o con comandi
espressamente scritti, ad esempio:
gedit primo.c
g++ -o primo primo.c
• Un generico comando di Linux è del tipo:
nomecomando –opzioni argomenti
• Nel nostro caso:
• g++ è il nome del comando che chiama il compilatore C++
• -o è l’opzione che permette di sceglire il nome del codice
eseguibile
• primo è il nome del codice eseguibile
• primo.c è il nome del file che deve essere compilato.
Le fasi della programmazione
Le fasi della programmazione
• Se la compilazione non ha dato errori, l’uscita
del compilatore è un file di nome
primo
• Cosa fare in caso di errori.
• Se ci sono errori in compilazione, questi
devono essere corretti altrimenti non si può
passare alla fase successiva di esecuzione. Il
compilatore evidenzia l’errore (o quasi)
scrivendo la riga in cui si trova e il tipo di
errore.
• Corretti gli errori si procede ad eseguire un
collaudo sul programma per testarne il buon
funzionamento.
• È un file contenente codice binario; con il comando
g++ si effettua anche il passo di link (collegamento
con altri moduli e con le librerie).
• Per mandare in esecuzione si scrive il comando
./primo
34
Il processo di programmazione
codice
sorgente
librerie
compilatore
(caricatore)
codice
sorgente
compilatore
codice
sorgente
librerie
file di
bytecode
librerie
interprete
file
eseguibile
interprete
programma
in esecuzione
programma
in esecuzione
programma
in esecuzione
linguaggio
Java
linguaggi
compilati
linguaggi
interpretati
Il linguaggio C++
Il linguaggio C++
Alfabeto
• Il linguaggio C++ (Bjarne Stroustrup 1983) è una
estensione del linguaggio C perché possiede i costrutti
della programmazione ad oggetti: classi e specifiche
per gestire ereditarietà, eccezioni, ecc.
• Nel C++ sono state introdotte alcune modifiche per
facilitare le operazioni di ingresso e uscita
(ampliamento della libreria standard con i flussi di
I/O).
• Lo standard del linguaggio è del 1998; sono state
eseguiti successivi ampliamenti presenti in (quasi) tutti
i compilatori C++.
• L’insieme dei caratteri usato è costituito dal
codice ASCII esteso.
• Le parole chiave, gli identificatori, i simboli
del linguaggio sono costruiti utilizzando solo i
primi 128 caratteri (ASCII standard):
spazio, cifre, lettere maiuscole e minuscole,
simboli speciali:
(){}[],.:;?!%\|/+-*"'<>=#&
(Cap. 13)
(par. 13.1)
35
Identificatori e Parole chiave
Regole per costruire i nomi
• Si chiamano identificatori i nomi delle
variabili e dei sottoprogrammi.
• Le parole chiave sono parole che hanno un
preciso significato e sono riservate: non
devono essere usate come nomi di
identificatori. Ad esempio:
• Nella costruzione dei nomi degli identificatori e delle
parole chiave si fa distinzione tra maiuscole e
minuscole: le parole chiave sono riservate se scritte in
minuscolo.
• Si utilizzano caratteri alfabetici e numerici, _,$
• Non si devono inserire spazi: lo spazio è un
separatore.
• Ogni nome di identificatore inizia con una lettera
alfabetica.
• int, if, main, …
• int:
nome di tipo di dato intero
• if:
nome della struttura di scelta
• main: nome del programma principale
• Esempi:
alfa
Alfa
(par. 13.2)
A lfa (no)
2area(no)
area2
Struttura di un programma
La struttura di un
programma
• Un programma nel linguaggio C++ è
composto da uno o più moduli, ciascuno dei
quali può contenere una o più funzioni e delle
istruzioni chiamate “direttive” per il
preprocessore, introdotte dal simbolo #.
• Uno ed uno solo di questi moduli contiene la
funzione main.
• Il main è il “programma principale”: viene
attivato direttamente dal Sistema Operativo.
(par. 13.3)
36
Struttura di un programma
• Esempio di programma costituito da tre moduli
#include …
int main() …
….istruzioni
//chiama funz1
//intestazione funz1
//intestazione funz2
….istruzioni
….istruzioni
//chiama funz2
//fine funz1
//fine main
primo.c
secondo.c
//fine funz2
terzo.c
Analisi di un semplice
programma
#include <iostream>
using namespace std;
int main () {/*programma che invia
all'uscita standard un messaggio */
cout<<"ciao a tutti"<<endl;
return 0;
}
• Occorre fare molta attenzione: il testo va inserito
esattamente come è presentato.
• Il programma invia all’uscita standard il messaggio
rappresentato da “ciao a tutti”.
Analisi di un semplice
programma
• Tradizionalmente, il primo programma che si scrive
quando si impara un linguaggio di programmazione ha
il compito di visualizzare sullo schermo un semplice
saluto.
• Utilizzando un editor di testi, costruiamo un file di
nome
ciao.c oppure ciao.cpp
• il nome del file serve per ricordare il significato del
programma; l’estensione c oppure cpp indica il
tipo di contenuto (si tratta di righe di testo scritte
nel linguaggio C o C++) ed è obbligatoria.
Analisi di un semplice
programma
• compiliamo il programma
g++ -o ciao ciao.c
• il compilatore genera un file eseguibile
(senza estensione)
• eseguiamo il programma
./ciao
• otteniamo la visualizzazione del messaggio
ciao a tutti
37
Analisi di un semplice
programma
Analisi di un semplice
programma
• L’istruzione include serve per inserire il
file di intestazione (header file) di nome
iostream che contiene le definizioni e le
istruzioni per gestire le operazioni di
ingresso/uscita.
• A seconda del sistema operativo usato (o della
versione del compilatore) si possono avere altri
nomi per i file da inserire:
• L’istruzione
include deve essere scritta
preceduta dal simbolo # posto in prima
colonna.
• Il file viene inserito nel punto in cui è scritta
l’istruzione.
• Se non sono presenti istruzioni di ingresso o
uscita tale istruzione non è necessaria (ad
esempio nel modulo di nome secondo.c
potrebbe non esserci alcuna istruzione di
lettura/scrittura).
• iostream.h
• stdio.h
• conio.h
oppure iostream.hpp
Analisi di un semplice
programma
Analisi di un semplice
programma
• L’istruzione
using namespace std;
indica una nuova versione dello standard per
I/O.
• I commenti sono istruzioni che non vengono
eseguite, ma servono ad introdurre frasi di
spiegazione e possono essere introdotti in due
diversi modi:
• Parentesi.
• Abbiamo parentesi tonde, quadre e graffe con
diversi significati.
• La coppia di parentesi graffe { } delimita le
istruzioni relative ad un blocco di istruzioni:
nell’esempio le istruzioni del programma
main.
// il commento occupa una sola riga
/* commento scritto
su più righe */
• È bene inserire dei commenti che indichino
cosa fa il programma o un gruppo di istruzioni
e quale è il significato delle variabili.
38
Analisi di un semplice
programma
Analisi di un semplice
programma
• Le unità di programma sono funzioni.
• In tutti i linguaggi di programmazione le
funzioni hanno un nome, possono avere 0, 1 o
più parametri, argomenti, di ingresso ed
hanno sempre un valore di ritorno.
• Gli argomenti sono scritti tra parentesi rotonde
e, se più di uno, sono separati da virgola.
• Ogni funzione che restituisce un valore deve avere
una esplicita istruzione di ritorno del tipo:
return espressione;
• dove espressione può essere una costante, una
variabile o una espressione (il cui valore viene
calcolato prima di essere restituito).
• Per il main si scrive:
return 0;
• Il valore 0 rappresenta un codice di ritorno al S.O.
che indica che l’esecuzione è andata a buon fine
(senza errori).
• Per convenzione il main è di tipo intero:
int main()
Analisi di un semplice
programma
• Ogni istruzione termina con un ;
• Ogni linguaggio gestisce una uscita standard
(vedremo poi altri tipi di uscite). Nel C++
l’uscita standard è rappresentata dal nome
cout
• Per poter inviare l’informazione al file
standard cout si utilizza l’operatore <<
(operatore di uscita).
Analisi di un semplice
programma
• Se non viene esplicitamente indicato, non si va mai a
capo: pertanto per non costruire righe troppo “larghe”
si dovrà indicare che la riga è finita e se ne inizia
un’altra.
• La fine della riga viene indicata con
endl
(end line)
• Per aggiungere al flusso di informazioni in uscita la
parola endl si concatena l’operatore di uscita
all’informazione precedente:
cout<<"ciao a tutti"<<endl;
39
Analisi di un semplice
programma
• Ciò che si vuole trasmettere in uscita è un
messaggio, cioè una stringa di caratteri.
• Le costanti stringa vengono scritte tra
virgolette:
"ciao a tutti "
• Le virgolette non fanno parte della stringa.
40