Wstęp do informatyki Schemat logiczny komputera Maszyna RAM

advertisement
Realizacja algorytmu przez komputer
Wstęp do informatyki
Wykład 2
UniwersytetWrocławski
2012
Schemat logiczny komputera
– urządzenia („układy”) wejścia i wyjścia:
komunikacja ze światem
– procesor: przetwarza informacje (wykonuje
instrukcje), steruje pozostałymi elementami
– pamięć: przechowuje informacje (dane i
programy)
– magistrale komunikacyjne: łączą pozostałe
elementy
Maszyna RAM
Tydzień temu:
– opis algorytmu w języku zrozumiałym
dla człowieka: schemat blokowy,
pseudokod.
Dziś:
– schemat logiczny komputera;
– zapis algorytmu w formie umożliwiającej
wykonanie go przez komputer;
Maszyna RAM
– taśma wejściowa: ciąg liczb całkowitych
– taśma wyjściowa : ciąg liczb całkowitych,
wypisywanych przez program
– procesor: wykonuje instrukcje
– pamięć: komórki 0, 1, 2, 3,…; przechowują
liczby całkowite
• Komórka 0: akumulator
– program: ciąg instrukcji do wykonania
– licznik rozkazów: wskazuje na instrukcję,
która aktualnie powinna być wykonana
RAM: szczegóły
taśma wejściowa
• Pamięć: nieskończona liczba komórek etykietowanych
0, 1, 2,..
• Komórka 0 nazywana rejestrem lub akumulatorem
• Każda komórka może przechowywać dowolną liczbę
całkowitą
• Taśma wejściowa i wyjściowa to urządzenia
sekwencyjne:
– taśma wejściowa: dane dla programu (wejście)
– taśma wyjściowa: wyniki programu (wyjście)
– Urządzenie sekwencyjne: program „przemieszcza” się tylko w
jednym kierunku, zawsze do następnej pozycji; każdy element
czytany tylko jeden raz;
taśma wyjściowa
1
Wykonanie programu
RAM: cykl główny procesora
• Pobierz instrukcję do wykonania –
wskazywaną przez licznik rozkazów
• Pobierz argumenty instrukcji do wykonania
• Wykonaj instrukcję
• Uaktualnij licznik rozkazów (o ile nie został
zmieniny przez instrukcję…)
Powtarzaj cykl główny procesora aż do
momentu gdy:
• Licznik rozkazów nie wskazuje na żadną
instrukcję
LUB
• Wykonana została instrukcja HALT
RAM: instrukcje
Składnia: <etykieta> <instrukcja> <argument>
Instrukcje wejścia/wyjścia:
Read Czyta kolejną liczbę z taśmy wejściowej
Write Wypisuje liczbę na końcu taśmy wyjściowej
RAM: instrukcje cd
Instrukcje arytmetyczne:
Add
Sub
Dodaj zawartość akumulatora i argument
Od akumulatora odejmij argument
Mult
Pomnóż zawartość akumulatora przez
argument
Podziel zawartość akumulatora przez
argument (wynik zakrąglony w dół)
Przesłanie do / z akumulatora:
Load Prześlij do akumulatora
Div
Store Prześlij zawartość akumulatora do innej
komórki
Rezultat jest zawsze umieszczany w akumulatorze.
RAM: instrukcje cd
Halt: zakończ działanie programu
Uwaga:
• halt nie jest konieczne,
• Jeśli licznik rozkazów wskazuje na pozycję nie
zawierającą żadnej instrukcji, program również
się zatrzymuje.
RAM: argumenty
Argument
Znaczenie
⟨liczba⟩
zawartość komórki o numerze
liczba
wartość liczba
adresownie pośrednie:
zawartość komórki, której numer
znajduje się w komórce o numerze
liczba
etykieta instrukcji
= ⟨liczba⟩
^ ⟨liczba⟩
⟨etykieta⟩
2
Argumenty instrukcji: przykład
• load 5:
zawartość komórki numer 5 pobierz (skopiuj) do
akumulatora
• load =5:
umieść liczbę 5 w akumulatorze
• load ^5:
do akumulatora pobierz (skopiuj) zawartość
komórki, której numer znajduje się w komórce 5
Argumenty instrukcji: przykład
div 5: podziel zawartość akumulatora przez
zawartość komórki numer 5
div =5: podziel zawartość akumulatora przez
liczbę 5
div ^5: podziel zawartość akumulatora przez
zawartość komórki, której numer znajduje
się w komórce 5
WYNIK jest zawsze umieszczany w
akumulatorze!
Argumenty instrukcji: przykład
Komórka
0
1
2
3
4
5
6
7
Wartość
90
15
Instrukcja
Nowa wartość
komórki 0
div 5
30 (90/3)
div =5
18 (90/5)
div ^5
6 (90/15)
Translacja na kod RAM:
Read 1
Read 2
Load 1
Add 2
Store 3
Write 3
Halt
Start
Read a, b
c ← a+b
write c
3
Stop
Skojarzenie z
komórkami pamięci:
1–a
2–b
3–c
Instrukcje RAM: skoki
Jump Skok bezwarunkowy
Jzero Skok pod warunkiem, że w akumulatorze
znajduje się zero
Jgtz
Kod RAM: przykład
Wejście: a, b – liczby
Wyjście: a + b
Skok pod warunkiem, że w akumulatorze
znajduje się liczba większa od zera
RAM przykład: maksimum z dwóch liczb
Wejście: a, b – liczby
Wyjście: maksimum liczb a, b
Czytaj a, b
no
Wypisz b
Argument: etykieta instrukcji
Etykieta: napis umieszczony z lewej strony
instrukcji (nie jest wymagana).
a-b>0
yes
Wypisz a
et1
Skojarzenie:
1–a
2–b
Ćwiczenie. uzupełnij powyższy
schemat o bloki Start i Stop.
et1
READ 1
READ 2
LOAD 1
SUB 2
JGTZ et1
WRITE 2
HALT
WRITE 1
HALT
3
Translacja schematu blokowego na kod RAM
• Skojarz zmienne z komórkami pamięci
• Translacja każdego bloku schematu
blokowego osobno! Zaznacz instrukcje
odpowiadające każdemu blokowi!
• Przekształć warunki sprawdzane w
schemacie blokowym do jednej z postaci
⟨wyrazenie⟩ = 0
⟨wyrazenie⟩ > 0
Używaj skoków aby zmienić odpowiednio
licznik rozkazów (przejść do
odpowiedniego fragmentu programu).
Schemat blokowy ⇒ RAM
tak
nie
et2
<expr> = 0
…
…
et3
…
• oblicz <expr>, wynik masz
w akumulatorze;
• wykonaj skok warunkowy:
jzero et1
• Kod odpowiadający „nie”
podaj pod instrukcją skoku
et1
… <expr> …
jzero et1
et2 …
…
jump et3
et1 …
…
jump et3
et3 …
Schemat blokowy ⇒ kod RAM
x ← <expr1> + <expr2>
Skojarzona z
komórką j
• oblicz <expr1>, zachowaj w pewnej komórce i
• oblicz <expr2>, wynik masz w akumulatorze!
• dodaj <expr1> do <expr2>:
add i
• zachowaj wynik w komórce j:
store j
Suma ciągu liczb
Wejście: ciąg liczb zakończony zerem!
Wyjście: suma wszystkich liczb w ciągu
Start
s←0
loop
Read a
nie
s←s+a
a=0
etkon
tak
Write s
Stop
Suma ciągu liczb, cd
Suma ciągu liczb – złożoność czasowa
Start
s←0
loop
nie
s←s+a
Read a
a=0
tak
etkon Write s
Skojarzenia komórek i
zmiennych:
1–a
2–s
Stop
load =0
store 2
loop read 1
load 1
JZERO etkon
load 2
add 1
store 2
jump loop
etkon write 2
Rozmiar danych:
n – liczba elementów do zsumowania (bez
ostatniego zera)
„Złożoność” schematu blokowego:
1 + 3n + 3 = 3n + 4
„Złożoność” programu w kodzie RAM:
2 + 7n + 4 = 7n + 6
„Która złożoność poprawna”?
4
Złożoność asymptotyczna
Notacja „dużego O”:
• ignorujemy stałe zależne od zapisu
algorytmu / modelu obliczeń;
• np., 10n, n+7, 112n są „podobne” (funkcje
liniowe);
• Lecz 100n and 2n2 istotnie się różnią!
Pyt.: Która z nich jest „większa”?
Odp.: 2n2
Pyt.: Dlaczego?
A: Szybciej rośnie!
Złożoność asymptotyczna - intuicja
f(n) = O(g(n))
wtw
g(n) rośnie co najmniej tak samo szybko jak
f(n) gdy n→∝
Złożoność asymptotyczna – przykłady
n2 / 1000 ≠ O(n), gdyż dla każdego c>0 mamy:
n2 / 1000 > c⋅n
dla nieskończenie wielu n.
W szczególności, nierówność
n2 / 1000 > c⋅n
zachodzi dla każdego n spełniającego
n > 1000⋅max(c,1).
Złożoność asymptotyczna
Notacja „dużego O” formalnie:
f(n) = O(g(n))
wtedy i tylko wtedy gdy (wtw)
istnieje stała c>0 i liczba naturalna m>0
takie, że f(n)≤c⋅g(n) dla każdego n>m.
Złożoność asymptotyczna – przykłady
100⋅n = O(n2), gdyż
100⋅n ≤ 100 ⋅ n2 dla każdego n>0.
55⋅n2+100n-10 = O(n2), gdyż
55⋅n2+100n-10 ≤ 57⋅n2 dla każdego n>60.
n2 =O(2n), gdyż
n2 ≤ 2n dla każdego n>5. [jak to pokazać?]
Złożoność asymptotyczna – przykłady
100⋅n = O(n)
100⋅n = O(n2)
n2 / 1000 ≠ O(n)
77⋅n+333 = O(n)
55⋅n2+100n-10 = O(n2)
55⋅n2+100n-10 = O(n3)
55⋅n2+100n-10 ≠ O(n)
n2 =O(2n)
2n≠ O(n2)
5
Suma ciągu liczb – złożoność czasowa
Sortowanie przez zliczanie
Rozmiar danych:
n – liczba elementów do zsumowania (bez
ostatniego zera)
„Złożoność” schematu blokowego:
1 + 3n + 3 = 3n + 4
„Złożoność” programu w kodzie RAM:
Problem
Wejście: n – liczba naturalna; a1,a2,...,an – ciąg
liczb naturalnych z przedziału [0,9]
Wyjście: elementy a1,a2,...,an wypisane w
porządku niemalejącym
2 + 7n + 4 = 7n + 6
Przykład
Wejście: 11; 0, 7, 9, 9, 2, 1, 6, 7, 6, 5, 5
Wyjście: 0, 1, 2, 5, 5, 6, 6, 7, 7, 9, 9
Złożoność asymptotyczna: O( n )
Sortowanie przez zliczanie
Algorytm
•Nadaj licznikom K0,…,K9 wartość zero.
•Wczytaj n
•Dla i=1,2,…,n powtarzaj:
•Wczytaj a
•Ka ← Ka+1
•Dla i=0, 1, 2, …,9 powtarzaj:
•Powtórz Ki razy:
•Wypisz i
Sortowanie przez zliczanie
Zamiast Ki używamy zmiennej złożonej K o
elementach K[0],…,K[9]:
•elementy K[0],…,K[9] tego samego typu;
•indeksowane kolejnymi liczbami naturalnymi
K – tablica (p. tablice w Ansi C)
Implementacja
•K[0],…,K[9] – sąsiednie komórki pamięci
licznik: „zlicza” liczbę wystąpień pewnego zdarzenia
Sortowanie przez zliczanie
Wstaw 0 do
K[0]..K[9]
wczytaj n
i←n
3
1
2
Assign 0 to
C[15]..C[24]
read C2
C3 ← C2
3
tak
Uwaga: komórkę Ci
będziemy też oznaczać przez
C[i]
i=0?
nie
wczytaj a
Sortowanie przez zliczanie
Skojarzenia:
K[0]..K[9]:
komórki 15..24
n : C2
i : C3
a : C4
j : C5
j ←0
4
2
Uwaga: komórkę Ci będziemy
też oznaczać przez C[i]
yes
C3 = 0 ?
no
7
read C4
5
Skojarzenia:
K[0]..K[9]: C[15]..C[24]
n : C2
i : C3
a : C4
j : C5
1
4
K[a] ← K[a]+1
tak
7
j>9?
C[C4+15] ← C[C4+15]+1
8
C5 > 9 ?
8
yes
nie
6
C5 ←0
5
i ← i-1
no
Powtórz K[j] razy: wypisz j
6
C3 ← C3-1
Repeat C[C5+15] times:
write C5
9
9
j← j+1
Stop
10
C5 ← C5 + 1
The end
10
6
Sortowanie przez zliczanie
Assign 0 to
C[15]..C[24]
C6 ← 24
1a
1b
1
yes
2
C6<15
no
C[C6] ← 0
1c
C6 ← C6-1
1d
load
store
L1b: load
sub
jgtz
load
store
load
sub
store
jump
=24
6
=15
6
l2
=0
^6
6
=1
6
L1b
Sortowanie przez zliczanie
#1a
#1b
C[C4+15] ← C[C4+15]+1
#1c
#1d
Sortowanie przez zliczanie
9
Repeat C[C5+15] times:
write C5
load
add
store
load
store
L9b: load
jgtz
jump
L9c: write
load
sub
store
jump
5
=15
7
^7
8
8
L9c
L10
5
8
=1
8
L9b
C7 ← C5+15
C8 ← C[C7]
#9a
9b
no
#9b
Write C5
9c
C8 ← C8-1
9d
10
#9c
#9d
Sortowanie przez zliczanie – złożoność
Rozmiar danych:
n?
n+k?
Pamięć:
proporcjonalna do k, czyli O( k )
Czas:
proporcjonalny do n+k, czyli O( n+k ) :
• gdy n > k: O( n + k ) = O( n )
• gdy n ≤ k: O( n + k ) = O( k )
4
#5
=15
7
^7
=1
^7
Sortowanie przez zliczanie ogólniej
Problem
Wejście: n – liczba naturalna; a1,a2,...,an – ciąg liczb
całkowitych z zakresu [0,k], k<n.
9a
C8>0
yes
5
load
add
store
load
add
store
Wyjście: elementy ciągu a1,a2,...,an wypisane w
porządku niemalejących
Rozwiązanie
Zamiast tablicy rozmiaru 10, użyj tablicy rozmiaru k.
Sortowanie przez zliczanie – złożoność
Czas:
proporcjonalny do n+k, czyli O( n+k ) :
gdy n > k: O( n + k ) = O( n )
gdy n ≤ k: O( n + k ) = O( k )
Uwaga
Jeśli k>>n:
• potrzebujemy większej pamięci niż długość ciągu!
• czas obliczeń proporcjonalny do k, czyli znacznie
większy od n (czy taki algorytm jest „praktyczny”?).
7
Podsumowanie
1. Maszyna RAM – model komputera:
• „Zmienna” liczbowa – komórka w pamięci
• Operacje arytmetyczne – wykonaj operację na
akumulatorze i (ewentualnie) zawartości innej
komórki
• Cykl główny procesora
• Pętle – skoki – licznik rozkazów.
2. Adresowanie pośrednie i jego zastosowania!
3. Notacja asymptotyczna w szacowaniu złożoności
4. Problem sortowania; sortowanie przez zliczanie: jak
działa? kiedy przydatne?
8
Download