WEBVTT

00:10.540 --> 00:11.980
Willkommen zur Vorlesung.

00:13.280 --> 00:17.120
Wir sind irgendwo mitten im Pipeline-Verarbeitungskapitel, naja nicht

00:17.120 --> 00:20.460
mitten, quasi am Ende vom Pipeline-Kapitel stehen geblieben.

00:21.660 --> 00:25.180
Eigentlich fehlte nur noch ein paar letzte Folien von der

00:25.180 --> 00:26.180
Sprungvorhersage.

00:26.720 --> 00:28.620
Die machen wir jetzt noch zu Ende und dann gehen wir ins nächste

00:28.620 --> 00:29.040
Kapitel.

00:30.960 --> 00:36.340
Also wir hatten gesehen, dass es Datenkonflikte gibt,

00:36.420 --> 00:39.120
Strukturkonflikte gibt und Steuerflusskonflikte gibt.

00:39.440 --> 00:40.940
Datenstruktur hatten wir erledigt.

00:41.780 --> 00:44.080
Steuerfluss hatten wir angefangen uns anzuschauen.

00:45.860 --> 00:47.860
Steuerflusskonflikte, das ist allgemein immer, wenn es schon

00:47.860 --> 00:48.760
Sprungbefehle gibt.

00:48.860 --> 00:52.080
Es gibt verschiedene Arten von Sprungbefehlen oder von

00:52.080 --> 00:54.080
Programmverzweigungen, sagen wir lieber.

00:54.520 --> 00:57.280
Und egal welche davon, die verursachen halt den potenziellen

00:57.280 --> 00:58.120
Steuerflusskonflikt.

00:58.820 --> 01:00.820
Da muss man gucken, wie man den auflösen kann.

01:01.080 --> 01:05.240
Das Problem ist halt eben, dass das Sprungziel noch nahe nicht bekannt

01:05.240 --> 01:07.200
ist, wenn der nächste Befehl geholt werden soll.

01:07.680 --> 01:09.420
Oder auch wenn es ein bedingter Sprung ist, weiß man auch gar nicht,

01:09.420 --> 01:10.780
ob der Sprung überhaupt genommen werden soll.

01:12.900 --> 01:15.860
Hatten wir hier ganz gut zu einem Beispiel einer Grafik

01:15.860 --> 01:16.640
zusammengefasst.

01:16.720 --> 01:20.260
In der DLX-Pipeline ist es halt eben so, dass am Ende der Memorystufe

01:20.260 --> 01:23.380
erst der neue Program-Counter-Wert geschrieben wird, im Falle, dass es

01:23.380 --> 01:25.300
ein Sprung ist und der Sprung auch wirklich genommen wird.

01:26.080 --> 01:29.480
Und logischerweise kann halt eben dann erst im Takt danach in der

01:29.480 --> 01:32.360
Instruction -Fetch-Stufe der Befehl vom Sprungziel geholt werden.

01:32.820 --> 01:34.520
Und dazwischen kann man sehen, da ist halt eine Lücke.

01:34.520 --> 01:37.260
Also hier sind, also die Lücke zeitlich hier.

01:37.520 --> 01:41.340
Da kommen also ein paar andere drei Befehle in die Pipeline rein, die

01:41.340 --> 01:44.140
eventuell gar nicht, ja die definitiv nicht vom Sprungziel sind.

01:44.540 --> 01:46.700
Die also nur dann richtig sind, wenn der Sprung nicht genommen werden

01:46.700 --> 01:47.000
sollte.

01:47.780 --> 01:49.820
Und dann hat man sich überlegt, wie kann man das Ganze schneller

01:49.820 --> 01:50.120
machen.

01:50.460 --> 01:53.240
Zum Beispiel könnte man es schneller machen, indem man versucht in der

01:53.240 --> 01:56.020
Decode -Stufe bereits alles zu bestimmen.

01:56.160 --> 02:00.980
Alles heißt hier, das Sprungziel berechnen und die Sprungbedingung

02:00.980 --> 02:01.580
auswerten.

02:01.660 --> 02:03.580
Also soll der Sprung genommen werden oder nicht, im Fall eines

02:03.580 --> 02:04.440
bedingten Sprunges.

02:05.880 --> 02:08.780
Wenn das so wäre, wenn wir das machen würden, alles in der Decode

02:08.780 --> 02:11.240
-Stufe, dann hätten wir halt eben die Verzögerung verkleinert.

02:11.300 --> 02:14.080
Wir würden am Ende der Decode-Stufe den Progen von unterwegs

02:14.080 --> 02:14.400
schreiben.

02:14.520 --> 02:17.220
So gesehen könnte für den nächsten Takt die Instruction-Fetch-Stufe

02:17.220 --> 02:19.200
den Befehl am Sprungzielrand schaffen.

02:20.320 --> 02:21.700
Hätten trotzdem noch eine Lücke hier.

02:21.820 --> 02:24.060
Also hier kann man sehen, hier ist trotzdem noch so ein Befehl, der

02:24.060 --> 02:25.040
hier zwischenpassen würde.

02:25.120 --> 02:28.020
Der wäre dann quasi, naja, nicht vom Sprungziel gewesen.

02:29.160 --> 02:32.540
Aber erstmal, wenn wir das machen würden, alles in der Decode-Stufe,

02:32.780 --> 02:33.860
das hätte auch ein paar Probleme.

02:33.980 --> 02:36.500
Hier nochmal die Pipeline, die wir die ganze Zeit schon benutzt haben,

02:36.580 --> 02:37.820
als Wiederholung eingeblendet.

02:38.540 --> 02:42.820
Wenn wir das alles in der Decode-Stufe machen würden, dann müssten wir

02:42.820 --> 02:49.940
das Sprungziel berechnen, also das Shiften, um aus Anzahl Befehle auf

02:49.940 --> 02:53.240
Anzahl Bytes zu kommen, plus die Addition von dem alten Program

02:53.240 --> 02:57.380
-Counter -Wert, plus eben den Offset, also der PC-relative Sprungziel.

02:57.600 --> 03:00.740
Die Berechnung müsste dann auch in die Decode-Stufe hier hinten

03:00.740 --> 03:01.620
drangequetscht werden.

03:02.160 --> 03:05.760
Und genauso auch beim bedingten Sprung, der Vergleich, ob der Sprung

03:05.760 --> 03:09.060
genommen werden soll, ja oder nein, müsste auch in die Decode-Stufe

03:09.060 --> 03:11.540
geschoben werden, also hier direkt an den Output des Register-Files

03:11.540 --> 03:12.320
sozusagen dran.

03:12.740 --> 03:15.740
Das macht zum einen mal die Decode-Stufe, naja, langsamer.

03:15.900 --> 03:18.380
Also ich habe halt viel mehr Arbeit, also sequentiell nacheinander

03:18.380 --> 03:19.920
durchzuführende Arbeit.

03:20.060 --> 03:20.920
Ist ja nicht parallel.

03:21.060 --> 03:23.660
Ich kann ja diese ALU, wenn ich die hier rüberschiebe, nicht parallel

03:23.660 --> 03:24.880
zum Register-File laufen lassen.

03:25.000 --> 03:26.980
Die benutzt ja den Output des Register-Files.

03:27.080 --> 03:28.360
Also das ist sequentiell nacheinander.

03:28.460 --> 03:30.160
So gesehen, die Frequenz wird beeinflusst werden.

03:30.560 --> 03:31.160
Eine Problem.

03:31.600 --> 03:36.140
Andere Probleme sind, ich kann dafür nicht die ALU benutzen, weil die

03:36.140 --> 03:39.580
ALU wird ja eigentlich für die normalen Arithmetik-Befehle in der

03:39.580 --> 03:41.220
Execute -Stufe gebraucht.

03:41.560 --> 03:44.520
Wenn ich die ALU jetzt beim Sprungbefehl hier benutzen würde, dann

03:44.520 --> 03:47.540
gäbe es halt eben ein Befehl, also sagen wir mal den Befehl zum

03:47.540 --> 03:52.940
Zeitpunkt T, der ist gerade in seiner Execute-Stufe und der Befehl

03:52.940 --> 03:55.660
danach, der wäre in dem Moment in seiner Decode-Stufe.

03:55.900 --> 03:59.280
Wenn der vorherige Befehl in der Execute-Stufe ein Arithmetik-Befehl

03:59.280 --> 04:02.580
ist und der Befehl danach ein Sprungbefehl ist, dann wollen die beide

04:02.580 --> 04:03.360
die ALU benutzen.

04:03.520 --> 04:04.480
Das geht nicht gleichzeitig.

04:04.700 --> 04:06.340
Das wäre ein Ressourcenkonflikt.

04:07.140 --> 04:09.060
Und um den aufzulösen, haben wir nicht so wahnsinnig viele

04:09.060 --> 04:09.440
Möglichkeiten.

04:09.600 --> 04:10.600
Wir müssen die ALU duplizieren.

04:10.700 --> 04:13.640
Also wir würden wirklich eine zweite ALU hier einbauen müssen, die

04:13.640 --> 04:15.160
dann ausschließlich für Sprungbefehle da ist.

04:15.660 --> 04:16.380
Das wären die Kosten.

04:20.010 --> 04:24.490
Wir hatten gesehen, einen Takt, hier hatten wir es gesehen, einen Takt

04:24.490 --> 04:25.830
haben wir trotzdem Verzögerung.

04:25.970 --> 04:29.650
Selbst wenn wir diese ganzen Kosten, also Frequenzverlust und Flächen

04:29.650 --> 04:33.230
-Overhead in Kauf nehmen würden, hätten wir trotzdem einen Takt hier

04:33.230 --> 04:34.550
irgendwie Verlust.

04:34.950 --> 04:37.130
Und den kann man ausnutzen, der heißt auch schon Delay Slots.

04:37.470 --> 04:39.770
Und das kann man ausnutzen bei Software-Lösungen.

04:40.030 --> 04:42.550
Man kann sagen, der Sprung, der in diesem Delay Slot steht, wird quasi

04:42.550 --> 04:44.650
immer ausgeführt, egal ob Sprung genommen oder nicht.

04:44.770 --> 04:46.730
So gesehen kann man den einfach mal zur Ausführung bringen und auch

04:46.730 --> 04:47.190
abschließen.

04:47.190 --> 04:51.690
Und dann ist es letztendlich am Compiler dafür zu sorgen, geeignete

04:51.690 --> 04:54.810
Befehle zu finden, die man in diesen Delay Slot wirklich einschieben

04:54.810 --> 04:55.070
kann.

04:57.310 --> 04:59.070
Ja, und das ist halt nicht so einfach eigentlich.

04:59.410 --> 05:04.090
Dann gibt es auch andere Lösungen, nämlich wie immer in der Hardware

05:04.090 --> 05:06.910
kann man es einfach mal die Ausführung anhalten.

05:07.310 --> 05:07.690
Geht immer.

05:08.210 --> 05:11.010
Dann werden zumindest mal nicht die falschen Befehle reingeholt, also

05:11.010 --> 05:13.930
die potenziell falschen, falsch, falls der Sprung genommen wird.

05:14.270 --> 05:15.770
Sonst werden einfach gar keine Befehle reingeholt.

05:16.030 --> 05:18.510
Und wenn ich weiß, was der Sprung tut, dann lasse ich die Pipeline

05:18.510 --> 05:19.110
weiterlaufen.

05:19.330 --> 05:20.810
Das ist halt eine ziemlich naive Lösung.

05:21.670 --> 05:24.530
Bringt keine Beschleunigung, also ob ich jetzt warte oder falsche

05:24.530 --> 05:26.870
Befehle hole, ist ein Unterschied, aber nicht so der Wahnsinnige.

05:27.430 --> 05:29.690
Aber es kostet auch quasi keinen Overhead.

05:30.530 --> 05:33.270
Und die andere Version, das ist die, die wir noch nicht ganz fertig

05:33.270 --> 05:34.730
haben, ist die Spekulation.

05:35.830 --> 05:39.850
Spekulation ist immer, ich rate, und zwar nicht mit einem Würfel,

05:40.010 --> 05:45.890
sondern möglichst gezielt, auf ein Ergebnis und mache dann schon mal

05:45.890 --> 05:48.730
weiter, als wäre ich mir relativ sicher, dass das Ergebnis auch

05:48.730 --> 05:50.470
zutrifft, also wirklich so ausgeführt wird.

05:51.110 --> 05:54.690
Und wenn ich mit dem Raten recht gehabt habe, dann ist das super, dann

05:54.690 --> 05:56.790
habe ich quasi keine Zeit verloren, kann einfach weitermachen.

05:57.170 --> 05:59.870
Wenn ich mit dem Raten falsch gelegen habe, dann muss ich eventuell

05:59.870 --> 06:01.050
irgendwas wieder aufräumen.

06:02.590 --> 06:06.090
In dem Fall ist das Raten halt einfach mal, ob ein Sprung genommen

06:06.090 --> 06:06.770
wird oder nicht.

06:06.850 --> 06:07.670
Das kann ich mal raten.

06:07.710 --> 06:09.530
Da gibt es verschiedene Vorhersageverfahren für.

06:10.190 --> 06:12.750
Und wenn ich richtig geraten habe, dann kann ich gleich

06:12.750 --> 06:13.290
weiterarbeiten.

06:15.970 --> 06:18.970
Ich muss allerdings nicht nur raten, ob der Sprung genommen wird,

06:19.070 --> 06:22.530
sondern für den Fall, ich sollte vielleicht lieber Vorhersagen sagen,

06:22.630 --> 06:26.590
nicht raten, für den Fall, dass meine Vorhersage war, Sprung wird

06:26.590 --> 06:31.570
genommen, dann muss ich ja auch wissen, okay, und wohin springe ich,

06:31.770 --> 06:33.490
wo geht der Sprung hin, wo geht es weiter?

06:33.850 --> 06:36.910
Also das Sprungziel, die Berechnung fehlt ja immer noch.

06:36.910 --> 06:41.570
Und damit ich jetzt nicht toll vorhergesagt habe, wo der Sprung

06:41.570 --> 06:44.810
hingeht, sondern dass ich auch wirklich weiterarbeiten kann, brauche

06:44.810 --> 06:48.830
ich halt irgendjemanden, der mir möglichst schnell sagen kann, wo geht

06:48.830 --> 06:51.010
der Sprung hin, falls er denn genommen wird.

06:51.330 --> 06:54.290
Und da hatten wir gesehen, gibt es diesen BranchTargetBuffer, der sich

06:54.290 --> 06:59.490
quasi einfach für ein paar, nicht alle, zuletzt beobachtete Sprünge

06:59.490 --> 07:01.250
merkt, wo die hingesprungen sind.

07:01.830 --> 07:04.830
Also das ist einfach quasi ein kleiner Speicher, könnte auch mal ein

07:04.830 --> 07:05.350
bisschen größer sein.

07:05.690 --> 07:07.510
Auf jeden Fall mal ein Speicher, der im Chip mit drin ist.

07:07.950 --> 07:11.070
Der ist initial, beim Starten, beim Booten, beim Anschalten, ist der

07:11.070 --> 07:12.010
leer, da steht nichts drin.

07:12.730 --> 07:15.470
Leer im Sinne von, natürlich steht da was drin, es gibt kein Leer, es

07:15.470 --> 07:16.210
gibt ein 0 oder 1.

07:16.590 --> 07:20.190
Aber da ist quasi beim Anschalten dieses ValidFlag gesagt, auf was

07:20.190 --> 07:22.610
auch immer hier drin steht, dieser Eintrag ist ungültig und somit ist

07:22.610 --> 07:22.850
er leer.

07:22.930 --> 07:24.230
Es ist kein gültiger Eintrag drin.

07:25.350 --> 07:28.770
Und wenn dann irgendwann mal ein Sprung beobachtet wird und beobachtet

07:28.770 --> 07:32.390
wird, oh, der Sprung wird genommen, dann wird er hier eingetragen in

07:32.390 --> 07:32.790
die Tabelle.

07:33.070 --> 07:36.450
Und zwar wird er eingetragen in genau eine Zeile.

07:36.690 --> 07:38.090
In welche Zeile wird er eingetragen?

07:38.370 --> 07:40.610
Hängt von der Adresse von dem Sprungbefehl ab.

07:40.950 --> 07:44.210
Also nicht die Adresse, wo er hinspringt, sondern die Adresse, wo der

07:44.210 --> 07:45.590
Sprungbefehl im Speicher stand.

07:46.210 --> 07:49.550
So, und diese Adresse, wo er im Speicher stand, die unteren paar Bits

07:49.550 --> 07:51.750
schenke ich mir, die sind ja quasi nur der ByteOffset, da ist ein

07:51.750 --> 07:53.990
Befehl, da sind die letzten beiden Bits immer 0, die brauche ich da

07:53.990 --> 07:54.470
nicht angucken.

07:54.470 --> 07:58.250
Aber die nächsten paar, ja, quasi noch least signifikant, abgesehen

07:58.250 --> 08:02.090
von denen hier, die sind noch leastiger, also die niederwertigsten

08:02.090 --> 08:05.190
Bits abgesehen von diesen beiden, die werden dann genutzt, um den

08:05.190 --> 08:07.510
Eintrag in der Tabelle hier zu adressieren.

08:07.670 --> 08:10.810
Also wenn hier n Bits sind, habe ich hier 2 hoch n Einträge.

08:12.230 --> 08:16.030
Damit wähle ich genau eine Zeile aus und in die Zeile schreibe ich

08:16.030 --> 08:16.690
dann was rein.

08:16.990 --> 08:20.870
Ich schreibe rein einmal die höchstwertigen Bits hier oben, das nennt

08:20.870 --> 08:25.030
man Tag, das brauche ich, um später herauszufinden, war es jetzt genau

08:25.030 --> 08:28.470
dieser Sprung, den ich da eingetragen habe, oder war es irgendein

08:28.470 --> 08:31.910
anderer Sprungbefehl, der irgendwo anders im Speicher steht, der nur

08:32.370 --> 08:35.090
zufällig bei den Bits hier genau die gleiche Bitkombination hat.

08:35.450 --> 08:37.970
Deswegen muss ich mir die höchstwertigen Bits auch noch merken, trage

08:37.970 --> 08:40.790
ich hier ein, sage jetzt, der Eintrag ist gültig, der ist jetzt

08:40.790 --> 08:44.450
wirklich bedeutungsvoll, da ist was Sinnhaftiges drin, und ich merke

08:44.450 --> 08:46.970
mir, 32 Bit, wo ist der denn hingesprungen.

08:47.450 --> 08:49.050
So, so füllt sich die Tabelle Stück für Stück.

08:49.330 --> 08:52.670
Wenn ich irgendwann einen Sprungbefehl entdecke, also beobachte, der

08:52.670 --> 08:56.590
genommen wird, dann kann es halt auch mal passieren, dass so ein

08:56.590 --> 08:58.230
Eintrag hier drin wieder überschrieben wird.

08:58.330 --> 09:02.370
Einfach der zuletzt beobachtete Sprung, der hat irgendeine Zeile

09:02.370 --> 09:06.150
hinschreiben will, der wird da eingetragen, was vorher drin stand,

09:06.530 --> 09:07.330
Pech, wird überschrieben.

09:09.430 --> 09:12.070
Und wenn ich jetzt, also so fülle ich die Tabelle, wie benutze ich

09:12.070 --> 09:12.250
sie?

09:12.650 --> 09:15.210
Ich benutze sie in der Instruction Fetch Stufe.

09:15.510 --> 09:18.130
In der Instruction Fetch Stufe habe ich am Anfang den Program Counter,

09:18.270 --> 09:21.570
der mir sagt, welcher Befehl aus dem Speicher eigentlich geholt werden

09:21.570 --> 09:21.870
soll.

09:22.830 --> 09:25.530
Und ich warte gar nicht ab, bis der Speicher sagt, was für ein Befehl

09:25.530 --> 09:25.910
das ist.

09:26.070 --> 09:29.030
Ich gucke nur auf die Adresse, steht im Program Counter drin, und die

09:29.030 --> 09:34.170
Adresse gebe ich auch an diesen Speicher dran und prüfe, anhand von

09:34.170 --> 09:37.850
der Adresse wähle ich eine Zeile aus, prüfe, was steht denn drin in

09:37.850 --> 09:38.310
der Zeile.

09:38.790 --> 09:40.230
Ist der Eintrag überhaupt gültig?

09:40.330 --> 09:42.130
Wenn nein, dann brauche ich nicht weitergucken.

09:42.410 --> 09:46.430
Wenn ja, wenn die Tags, die oberen Bits, die hier gespeichert sind,

09:46.530 --> 09:50.870
genau die Bits von meiner Adresse sind, dann weiß ich, der Befehl, den

09:50.870 --> 09:54.290
ich jetzt gerade erst parallel zu diesem Zugriff hier aus dem Speicher

09:54.290 --> 09:56.970
hole, ich habe ihn noch gar nicht, aber ich weiß jetzt schon, das ist

09:56.970 --> 10:00.210
ein Sprungbefehl, der wurde mindestens einmal schon mal ausgeführt,

10:00.310 --> 10:03.830
also Sprung genommen, und damals ist er hierhin gesprungen.

10:04.750 --> 10:09.110
Und so gesehen kann ich dann quasi im nächsten Takt gleich für die

10:09.110 --> 10:11.590
Annahme, dass meine Sprungvorhersage sagt, der Sprung wird jetzt

10:11.590 --> 10:15.110
wieder genommen, dann weiß ich gleich, das ist die Adresse, von da

10:15.110 --> 10:16.410
musst du den nächsten Befehl holen.

10:16.550 --> 10:20.430
So kann ich den Branch Target Buffer benutzen, um quasi sofort zu

10:20.430 --> 10:22.970
wissen, wenn der Sprung genommen wird, wo geht's dann weiter.

10:24.970 --> 10:27.970
Wir hatten gesehen, gucken wir nochmal kurz, es gibt auch indirekte

10:27.970 --> 10:30.690
Sprünge, indirekt im Sinne von, die haben nicht nur zwei Sprungziele,

10:30.790 --> 10:35.390
wir hatten Return gesehen, von der Funktion, die quasi zurückgeht, und

10:35.390 --> 10:38.890
wir hatten gesehen für Switchcase die Implementierung, die quasi mit

10:38.890 --> 10:42.950
dem Jump Register gemacht wird, also quasi Sprünge an Adresse, deren

10:42.950 --> 10:46.590
Wert, also deren Zahl in einem Register drinsteht, naja, da kann jedes

10:46.590 --> 10:47.610
Mal was anderes drinstehen.

10:48.090 --> 10:49.870
So gesehen, da weiß ich nicht genau, wo es hingeht.

10:50.230 --> 10:53.890
Da hilft mir der Branch Target Buffer nicht wirklich weiter, manche

10:53.890 --> 10:59.190
CPUs haben dann tatsächlich einen neuen Eintrag für jedes neu

10:59.190 --> 11:03.330
beobachtete Sprungziel, hätten dann quasi mehrere zu auswählen.

11:03.990 --> 11:06.390
Einen Spezialfall haben wir noch gesehen für Rücksprünge, gibt es

11:06.390 --> 11:08.750
manche CPUs, die haben einen speziellen Stack, wo sie quasi bei

11:08.750 --> 11:12.070
Funktionsaufrufen Einträge auf den Stack draufschreiben, weil sie

11:12.070 --> 11:14.930
wissen, wann auch immer der Return kommt, dann werde ich genau dahin

11:14.930 --> 11:16.910
zurückspringen, wo ich quasi hergekommen bin.

11:17.310 --> 11:19.410
Genau dahin im Sinne von, der befiehlt danach.

11:21.910 --> 11:25.510
Gut, ja, und dann geht es noch um die Entscheidung, wie mache ich

11:25.510 --> 11:30.610
eigentlich die Vorhersage, ob der Sprung vermutlich genommen werden

11:30.610 --> 11:32.570
wird, oder halt eben nicht.

11:32.690 --> 11:35.810
Da gibt es verschiedene Vorhersagemöglichkeiten, die statischen und

11:35.810 --> 11:36.450
die dynamischen.

11:36.830 --> 11:39.210
Und hier ist eine Zusammenfassung von den statischen, die hatten wir

11:39.210 --> 11:40.670
ein bisschen ausführlicher gesehen, aber wir gucken nur die

11:40.670 --> 11:41.450
Zusammenfassung an.

11:42.710 --> 11:45.910
Es gibt zum Beispiel eine Vorhersage, die heißt, always not taken, das

11:45.910 --> 11:46.570
ist die einfachste.

11:46.770 --> 11:49.050
Die Annahme ist immer, der Sprung wird nicht genommen.

11:49.490 --> 11:53.730
Ich mache die Ausführung da weiter, ja, mit dem nächsten Befehl, also

11:53.730 --> 11:56.450
mit dem Befehl plus 4, also der direkt nächste Befehl danach, nicht am

11:56.450 --> 11:58.710
Sprung zieht, sondern einfach der danach kommt, da mache ich die

11:58.710 --> 11:59.430
Ausführung weiter.

12:01.950 --> 12:05.750
Ja, es ist die einfachste Version, der muss quasi nur den nächsten

12:05.750 --> 12:09.230
Befehl holen, der ist lokal, das ist gut für Befehlscaches, die wir

12:09.230 --> 12:12.250
uns später noch angucken werden, aber in der Praxis funktioniert er

12:12.250 --> 12:14.730
ziemlich schlecht, weil er bei Schleifen halt immer falsch liegt.

12:15.110 --> 12:18.990
Bei Schleifen habe ich ja quasi immer so häufig, wie die Schleife

12:18.990 --> 12:23.210
ausgeführt wird, so häufig muss ich irgendwie springen und das zeigt

12:23.210 --> 12:24.070
er jedes Mal falsch vorher.

12:24.150 --> 12:25.370
So gesehen, dafür ist er echt nicht gut.

12:25.770 --> 12:28.490
Deswegen gab es danach die Variante, dass die Vorhersage ist always

12:28.490 --> 12:32.030
taken, als wäre der Sprung quasi immer ausgeführt worden.

12:32.490 --> 12:34.350
Das ist sehr gut bei Schleifen, weil die Schleifen werden halt

12:34.350 --> 12:37.390
häufiger ausgeführt als nicht ausgeführt, also sie werden quasi nur

12:37.390 --> 12:40.490
ein einziges Mal verlassen und zwischendurch häufiger iterieren sie.

12:41.890 --> 12:46.510
Hat aber den Nachteil, always taken, ich brauche die Zieladresse, also

12:46.510 --> 12:48.690
ich brauche diesen BranchTargetBuffer, ohne geht es nicht.

12:48.690 --> 12:52.870
Und das Sprungziel ist ja für gewöhnlich mal wo, ganz wo anders.

12:53.070 --> 12:55.590
Also muss ich diese Adresse von mal wo, ganz wo anders erstmal

12:55.590 --> 12:58.950
heranschaffen und sobald wir irgendwann die InstructionCaches angucken

12:58.950 --> 13:00.490
werden, werden wir sehen, warum das schlecht ist.

13:00.870 --> 13:03.770
Es ist im Wesentlichen deswegen schlecht, weil die InstructionCaches

13:03.770 --> 13:12.990
gut darin sind, lokal benutzte Bereiche, Adressbereiche vorrätig zu

13:12.990 --> 13:13.270
halten.

13:13.550 --> 13:17.390
Also die Chance, dass der Befehl danach der nächste in diesem

13:17.390 --> 13:18.930
InstructionCaches ist, ist ziemlich gut.

13:19.410 --> 13:21.750
Und die Chance, dass das Sprungziel im InstructionCaches ist, ist

13:21.750 --> 13:22.650
deutlich weniger gut.

13:23.050 --> 13:24.990
Und wenn es nicht im InstructionCaches ist, muss es aus dem

13:24.990 --> 13:27.090
Hauptspeicher geholt werden und Hauptspeicher ist langsam.

13:27.310 --> 13:31.930
Und dadurch ist das prinzipiell immer langsamer, plus das Sprungziel

13:31.930 --> 13:34.350
wird dann auch in den InstructionCache eingetragen, verdrängt dabei

13:34.350 --> 13:38.810
eventuell andere nützliche Sachen, was schlecht ist, wenn es umsonst

13:38.810 --> 13:39.630
geholt worden ist.

13:42.010 --> 13:43.790
Gibt es Kompromisse, Varianten dazwischen?

13:43.990 --> 13:46.270
Zum Beispiel backward-taken, forward-not-taken mit der Idee,

13:46.650 --> 13:50.330
Rücksprünge, backward, ist meistens für Schleifen benutzt, die werden

13:50.330 --> 13:52.090
häufiger genommen als nicht genommen.

13:52.930 --> 13:55.170
Wohingegen forward ist häufiger für if-then-else.

13:55.590 --> 13:57.190
Naja, da kommt es halt sehr auf die Anwendung an.

13:57.290 --> 13:57.950
Ja, 50-50.

13:58.290 --> 14:01.150
Dann könnte man sagen, gut, da ich es da wirklich nicht so genau weiß,

14:01.550 --> 14:04.150
sage ich halt diese not-taken, damit ich meinen Cache in Ruhe lasse,

14:04.210 --> 14:07.390
dass ich da für die, wo ich es echt nicht nur 50-50 weiß, dass ich da

14:07.390 --> 14:09.790
den Cache in Ruhe lasse, nicht die falschen Befehle reinhole.

14:10.390 --> 14:19.910
Und es gibt auch noch Profiling-basierte sprungspezifische Hinweise im

14:19.910 --> 14:23.110
Sinne von, man lässt die Anwendung mal laufen, für eine gewisse

14:23.110 --> 14:27.550
charakteristische, typische, repräsentative Eingabe und beobachtet

14:27.550 --> 14:29.990
dabei einfach, welcher Sprung wird wie häufig genommen, wie häufig

14:29.990 --> 14:33.070
nicht genommen und das von den beiden, was häufiger war, das kodiert

14:33.070 --> 14:34.270
man in den Befehl mit rein.

14:34.410 --> 14:38.070
Also der Kodierer, der der Befehl sagt, ich bin ein Sprung, ich bin

14:38.070 --> 14:40.830
ein bedingter Sprung, Bedingung ausrechnen musst du so und so machen,

14:40.950 --> 14:44.690
Sprung ziehen musst du so und so machen und ich werde vermutlich taken

14:44.690 --> 14:46.050
oder not taken sein.

14:46.130 --> 14:48.830
Das kann man quasi da mit rein kodieren in den Assemblerbefehl und das

14:48.830 --> 14:50.230
kann dann auch als Vorhersage benutzt werden.

14:52.710 --> 14:55.950
Ja, dann hatten wir die dynamischen Sprungvorhersagen angeschaut oder

14:55.950 --> 14:56.690
angefangen zumindest.

14:56.790 --> 14:58.430
Die einfachste davon hatten wir, glaube ich, durch.

14:58.430 --> 15:01.810
Das ist nämlich genau die Einbildvorhersage.

15:02.290 --> 15:06.730
Also dynamisch heißt hier erstmal einfach, dass die Vorhersage zur

15:06.730 --> 15:10.590
Laufzeit nicht konstant ist, wie bei den statischen, sondern, dass die

15:10.590 --> 15:12.270
Vorhersage sich zur Laufzeit ändert.

15:12.590 --> 15:16.230
Für ein und denselben Sprungbefehl wird zu einem gewissen Zeitpunkt

15:16.230 --> 15:19.010
vorhergesagt werden, der wird genommen und zu einem anderen Zeitpunkt

15:19.010 --> 15:20.990
wird vorhergesagt werden, der wird nicht genommen.

15:22.170 --> 15:24.630
Also wir haben jetzt erstmal die Möglichkeit, es zu ändern.

15:24.810 --> 15:27.050
Jetzt müssen wir mal gucken, wie wir es gut machen.

15:27.550 --> 15:29.830
Und hier ist die erste Version, wie wir es nicht gut machen.

15:29.890 --> 15:31.110
Aber zumindest mal besser als statisch.

15:32.030 --> 15:35.130
Es gibt einfach eine kleine Zustandsmaschine, bestehend aus zwei

15:35.130 --> 15:37.150
Zuständen, die sagt halt einfach, der Sprung wird wahrscheinlich

15:37.150 --> 15:39.970
genommen oder wahrscheinlich nicht genommen und der orientiert sich

15:39.970 --> 15:43.750
einfach an der Historie, im Sinne von, das, was auch immer der letzte

15:43.750 --> 15:46.650
Sprungbefehl, der letzte bedingte Sprungbefehl gemacht hat, wird

15:46.650 --> 15:49.390
vermutlich der nächste Sprungbefehl auch machen.

15:49.750 --> 15:53.690
Das ist einfach hier die Annahme von diesem Vorhersagemodell.

15:57.350 --> 15:58.730
Es gibt beides.

16:00.990 --> 16:03.830
In der einfachen Version, die wir uns hier anschauen, ist es global,

16:03.950 --> 16:06.690
im Sinne von einer einzigen Zustandsmaschine für das ganze System.

16:07.270 --> 16:10.310
Und die besseren Sprungvorhersagen, die dann allerdings nicht diesen

16:10.310 --> 16:13.810
einen Bitprediktor nehmen, sondern einen anderen, da gibt es dann

16:13.810 --> 16:15.350
Einträge pro Sprung.

16:15.350 --> 16:18.590
Und wenn ich sage pro Sprung, dann meine ich nicht wirklich für jeden

16:18.590 --> 16:21.310
Sprung, weil ich weiß ja gar nicht, wie viele es geben könnte, sondern

16:21.310 --> 16:25.070
es gibt eine Tabelle einer gewissen Größe, wo dann von mir aus tausend

16:25.070 --> 16:28.090
Sprünge reinpassen und dann wird halt wieder geguckt, die letzten

16:28.090 --> 16:31.410
tausend Ausgeführten, die haben dann so ein Lernverfahren da drin.

16:31.710 --> 16:33.370
Dann wird für die letzten tausend Sprünge was gemerkt.

16:33.910 --> 16:37.270
Da sage ich nachher noch ganz kurz was zu, aber diese etwas

16:37.270 --> 16:39.530
komplizierteren Verfahren sind halt eben nicht mehr im Rahmen von

16:39.530 --> 16:40.110
dieser Vorlesung.

16:40.110 --> 16:41.570
Hier kommen halt nur die einfachen Verfahren dran.

16:42.170 --> 16:45.130
Es hat halt eben mehr Hardwareaufwand, wenn man mehrere Einträge haben

16:45.130 --> 16:46.710
muss, aber es lohnt sich auch wirklich.

16:46.790 --> 16:47.950
Es kommt wirklich was besseres bei raus.

16:53.690 --> 16:54.090
Beispiel.

16:55.630 --> 16:56.430
Verschattete Schleife.

16:56.830 --> 16:58.050
Irgendwie eine äußere und eine innere.

16:58.790 --> 17:02.230
Und jetzt habe ich eine Fehlvorhersage.

17:02.370 --> 17:03.410
Wann habe ich eine Fehlvorhersage?

17:03.410 --> 17:05.530
Also erstmal, ich habe die innere Schleife, die läuft, die läuft

17:05.530 --> 17:07.910
viermal, keine Ahnung, sagen wir tausendmal, also ein bisschen

17:07.910 --> 17:08.290
häufiger.

17:09.550 --> 17:16.470
Und solange die Schleife iteriert, die letzte Iteration hat dafür

17:16.470 --> 17:18.870
gesorgt, dass ein Sprung genommen wird, also wird für die nächste

17:18.870 --> 17:20.410
Iteration auch taken vorher gesagt.

17:20.770 --> 17:23.610
Also solange die Schleife läuft, so abgesehen vom ersten und letzten

17:23.610 --> 17:26.250
Befehl, ist die Vorhersage immer taken und somit immer richtig.

17:26.250 --> 17:29.490
Und irgendwann, wenn die Schleife verlassen wird, also bei der letzten

17:29.490 --> 17:32.230
Iteration, ist die Vorhersage ganz normal, wie immer.

17:32.910 --> 17:35.470
Die wird genommen, der Sprung, aber es war die letzte Iteration,

17:35.550 --> 17:36.150
konnte er nicht wissen.

17:36.550 --> 17:38.510
Und deswegen wird jetzt der Sprung nicht genommen, Schleife wird

17:38.510 --> 17:38.850
verlassen.

17:39.370 --> 17:42.190
Jetzt komme ich in die äußere Schleife rein, also ich habe eine

17:42.190 --> 17:43.950
Fehlvorhersage, weil Schleife wird verlassen.

17:44.290 --> 17:48.250
Jetzt komme ich in die äußere Schleife rein, die iteriert ja nochmal,

17:48.570 --> 17:49.010
wahrscheinlich.

17:49.010 --> 17:51.790
Das heißt, da wird der Sprung wieder genommen, obwohl ich gerade nicht

17:51.790 --> 17:52.870
genommen vorher gesagt habe.

17:52.970 --> 17:55.950
Also ich habe quasi bei jedem Verlassen der äußeren Schleife zwei

17:55.950 --> 17:56.850
Fehlvorhersagen.

17:57.290 --> 18:00.830
Eine beim Verlassen der äußeren und eine für die nächste Iteration.

18:01.050 --> 18:04.150
Sorry, eine beim Verlassen der inneren Schleife.

18:04.270 --> 18:07.250
Wenn die verlassen wird, habe ich eine Fehlvorhersage und dann noch

18:07.250 --> 18:10.370
eine Fehlvorhersage, weil die äußere noch ihre nächste Iteration

18:10.370 --> 18:10.910
wieder macht.

18:11.930 --> 18:14.990
Das sehen wir hier nochmal ausführlicher.

18:16.870 --> 18:18.790
Das war, glaube ich, die letzte Folie, die wir hatten.

18:20.950 --> 18:23.670
Hier ist einfach zwei Schleifen nacheinander, man kann es auch mit

18:23.670 --> 18:24.990
zwei Verschachtelten machen, das ist gerade egal.

18:25.470 --> 18:27.610
Jetzt habe ich einfach zwei Schleifen nacheinander und hier

18:27.610 --> 18:33.030
aufgeschrieben, was bei den verschiedenen Iterationen der Schleife

18:33.030 --> 18:33.310
passiert.

18:34.470 --> 18:38.710
Bei der ersten Iteration von der ersten Schleife, nehmen wir mal an,

18:38.810 --> 18:41.850
wir sind gerade im Zustand, dass die Vorhersage ist Not Taken.

18:42.790 --> 18:45.230
Dann hat die Vorhersage leider falsch gelegen, denn die erste

18:45.230 --> 18:47.830
Iteration führt ja zur zweiten, also das iteriert jetzt hier eine

18:47.830 --> 18:48.030
Weile.

18:49.070 --> 18:53.390
Nach dieser ersten Vorhersage wird die Vorhersage gewechselt, weil der

18:53.390 --> 18:55.770
Schwung wurde ja doch genommen, deswegen wird auf Taken gewechselt die

18:55.770 --> 18:56.290
Vorhersage.

18:56.290 --> 19:00.830
Und damit hat er auch für die nächsten paar Iterationen recht, bis zur

19:00.830 --> 19:04.130
letzten Iteration.

19:04.470 --> 19:08.390
Bei der letzten Iteration ist die Vorhersage weiterhin, dass wohl noch

19:08.390 --> 19:10.550
eine kommen wird, aber irgendwann ist halt mal die letzte da.

19:11.030 --> 19:13.030
Bei der letzten wird der Schwung halt eben nicht genommen, also ist

19:13.030 --> 19:14.450
hier wieder eine falsche Vorhersage.

19:15.070 --> 19:18.770
Jetzt toggelt die Vorhersage von genommen auf nicht genommen, das kann

19:18.770 --> 19:19.290
man jetzt genau sehen.

19:19.290 --> 19:23.810
Das ist das Verlassen der einen Schleife, das Betreten der nächsten

19:23.810 --> 19:24.270
Schleife.

19:24.610 --> 19:27.010
Für die nächste Schleife ist die Vorhersage jetzt nicht genommen, aber

19:27.010 --> 19:29.050
die nächste Schleife iteriert hier wieder, also der Schwung wird

19:29.050 --> 19:29.330
genommen.

19:29.550 --> 19:31.470
Das ist jetzt die zweite falsche Vorhersage.

19:31.870 --> 19:33.330
Und die zwei habe ich halt eben immer.

19:35.410 --> 19:38.050
Äußere und Innere, zwei Schleifen nacheinander, ist gerade egal.

19:38.410 --> 19:39.870
Die beiden falschen habe ich quasi immer.

19:40.250 --> 19:42.210
Jetzt ist halt hier dumm gelaufen, dass ich am Anfang hier noch eine

19:42.210 --> 19:42.450
hatte.

19:42.790 --> 19:44.870
Und ganz am Ende habe ich halt eben noch eine.

19:46.030 --> 19:50.970
Habe ich in der Summe 16 von 20 Sprüngen richtig vorhergesagt, also 80

19:50.970 --> 19:51.670
% richtig.

19:51.910 --> 19:54.670
Was für so eine billige Hardware gar nicht so schlecht ist.

19:56.930 --> 19:58.310
Ja, wie kann man es besser machen?

19:58.630 --> 20:01.750
Wenn es einen 1-Bit-Prediktor gibt, könnte man ja auch einen 2-Bit

20:01.750 --> 20:02.430
-Prediktor nehmen.

20:02.610 --> 20:04.470
Dann können wir auch gleich n-Bit-Prediktor hinschreiben.

20:06.110 --> 20:07.610
Wobei n gleich 2.

20:07.890 --> 20:11.930
Also 3-Bit-Prediktoren, man kann sich vieles ausdenken, aber machen

20:11.930 --> 20:12.550
tut es halt keiner.

20:12.550 --> 20:16.410
Also mehr als 2-Bits dafür benutzen, nutzt eigentlich nichts.

20:16.510 --> 20:17.670
Bringt keinen echten Vorteil mehr.

20:18.690 --> 20:21.210
So, wenn ich jetzt 2-Bit habe, habe ich offensichtlich 4 Zustände.

20:21.530 --> 20:22.850
Jetzt muss ich den Kindern Namen geben.

20:23.830 --> 20:26.830
Dann nehmen wir mal Strongly Taken oder einfach Taken.

20:27.250 --> 20:29.710
Und dann gibt es halt eben noch als Abschwächung Weekly Taken.

20:29.990 --> 20:31.670
Vermutlich, bin mir nicht mehr so ganz sicher.

20:32.210 --> 20:34.430
Und dann Weekly Not Taken, Strongly Not Taken.

20:34.830 --> 20:38.070
Und die Überführungsfunktion wäre einfach ein Sättigungszähler.

20:38.070 --> 20:40.730
Im Sinne von, wenn man sich das vorstellt als die Zahl, die hier

20:40.730 --> 20:41.390
kodiert ist.

20:41.490 --> 20:43.150
00, 01, 10, 11.

20:43.850 --> 20:46.510
Für jedes Taken wird quasi plus 1 gerechnet.

20:46.870 --> 20:48.890
Also hier auch, dann Taken kommen wir hier hin, plus 1.

20:49.170 --> 20:51.690
Und Sättigung im Sinne von, dann bleiben wir halt hier.

20:51.830 --> 20:53.850
Größer als 11 wird nicht, also kein Überlauf.

20:53.910 --> 20:54.890
Überlauf muss verhindert werden.

20:55.490 --> 20:57.470
Genauso Zähler in anderen Richtungen.

20:57.590 --> 21:00.210
Für jedes Not Taken rechnen wir minus 1, minus 1, minus 1.

21:00.510 --> 21:02.730
Und bei 00 bleiben wir dann, kein Unterlauf.

21:03.310 --> 21:08.130
Ja, also das wäre schon der Zustandsautomat dazu.

21:08.510 --> 21:11.230
Gucken wir uns das Ganze wieder an einem Beispiel an.

21:11.630 --> 21:13.470
Jetzt haben wir bei inneren Schleifen oder halt bei zweien

21:13.470 --> 21:15.930
nacheinander, ist gerade egal, nur noch eine falsche Vorhersage.

21:16.550 --> 21:17.350
Das schauen wir uns mal an.

21:17.710 --> 21:20.530
Wir haben jetzt quasi die Zustände, die ich im folgenden so abkürze.

21:20.870 --> 21:23.490
Not Taken für Strongly Not Taken.

21:23.850 --> 21:27.250
Dann haben wir Weekly Not Taken, Weekly Taken und Strongly Taken oder

21:27.250 --> 21:27.770
einfach Taken.

21:28.230 --> 21:29.530
Das gleiche Beispiel wie vorhin.

21:30.730 --> 21:34.370
Jetzt nehmen wir mal an, dass der Startzustand, irgendwo müssen wir

21:34.370 --> 21:37.170
halt mal anfangen, bei Not Taken war.

21:37.370 --> 21:39.110
Irgendwo muss er halt sein, zum Beispiel Not Taken.

21:39.790 --> 21:42.250
Dann würde das Ganze wie folgt aussehen.

21:42.690 --> 21:47.890
Bei der ersten Iteration, die Vorhersage war Not Taken, aber die erste

21:47.890 --> 21:49.650
Iteration führt ja zur zweiten.

21:50.070 --> 21:51.850
Also der Sprung wird genommen.

21:52.050 --> 21:53.930
So gesehen war die Vorhersage auf jeden Fall mal falsch.

21:54.910 --> 21:58.450
Wir ändern unsere Vorhersage von Not Taken auf Weekly Not Taken.

21:58.450 --> 22:01.110
Wir hatten Not Taken, Sprung wird aber doch genommen.

22:01.530 --> 22:02.510
Nochmal kurz zurück hier.

22:03.150 --> 22:07.550
Wir hatten Not Taken, Sprung wird aber doch genommen.

22:08.070 --> 22:11.090
Also gehen wir auf die Vorhersage Weekly Not Taken.

22:13.930 --> 22:16.990
Jetzt sind wir in der zweiten Iteration, haben die Vorhersage Weekly

22:16.990 --> 22:17.590
Not Taken.

22:17.870 --> 22:18.890
Jetzt muss ich kurz unterscheiden.

22:19.290 --> 22:22.890
Wir sind im Zustand Weekly Not Taken.

22:23.030 --> 22:24.110
Was ist die Vorhersage?

22:24.410 --> 22:27.390
Die Vorhersage ist nur Taken oder Not Taken.

22:27.390 --> 22:30.350
Also mit einem vielleicht genommen kann ich nichts anfangen.

22:30.450 --> 22:32.550
Ich muss wissen, soll ich zum Sprung-Ziel oder soll ich mit dem

22:32.550 --> 22:33.470
nächsten Befehl weitermachen.

22:33.610 --> 22:35.410
Mit Weekly kann ich da nichts anfangen.

22:35.790 --> 22:41.170
Weekly ist ein internes Detail, was aber für die Vorhersagegenauigkeit

22:41.170 --> 22:42.230
irgendwie schon wichtig ist.

22:42.310 --> 22:44.450
Aber letztendlich muss ich mich entscheiden, will ich am Sprung-Ziel

22:44.450 --> 22:46.070
weitermachen oder beim nächsten Befehl.

22:46.550 --> 22:48.270
Und darum wird quasi, gehen wir mal kurz zurück.

22:49.910 --> 22:52.190
Bei dem wird vorhergesagt, der Sprung wird genommen.

22:52.630 --> 22:54.590
Bei dem wird auch vorhergesagt, der Sprung wird genommen.

22:54.590 --> 22:56.530
Dass er sich hier nicht mehr ganz so sicher ist.

22:56.630 --> 22:56.850
Weekly.

22:57.270 --> 22:58.010
Das ist egal.

22:58.450 --> 23:02.530
Bei beiden wird vorhergesagt, mach da weiter, wo das Sprung-Ziel ist.

23:03.750 --> 23:06.850
Anders ausgedrückt, das Most Significant wird hier vorne.

23:07.050 --> 23:09.790
Wenn das 1 ist, dann wird am Sprung-Ziel weitergemacht.

23:10.150 --> 23:12.990
Wenn das 0 ist, dann ist die Annahme, der Sprung wird nicht genommen.

23:13.290 --> 23:14.590
Weekly oder Strongly ist egal.

23:15.150 --> 23:16.270
Die Annahme, der Sprung wird nicht genommen.

23:16.570 --> 23:17.870
Mach am nächsten Befehl weiter.

23:18.990 --> 23:22.890
Das heißt, der Zustand ist Weekly Not Taken.

23:22.890 --> 23:25.970
Das heißt, die Vorhersage ist Not Taken.

23:26.290 --> 23:28.110
Soll heißen, mach beim nächsten Befehl weiter.

23:28.650 --> 23:29.830
Aber leider falsch.

23:29.950 --> 23:30.790
Wir sind ja immer noch in der Schleife.

23:31.110 --> 23:33.150
Wir sind ja quasi erst in der zweiten Generation der Schleife

23:33.150 --> 23:33.490
angekommen.

23:33.590 --> 23:34.650
Natürlich wird der Sprung genommen.

23:34.850 --> 23:37.370
Natürlich im Sinne von, ich der den C-Code daneben stehen habe, kann

23:37.370 --> 23:37.750
das sehen.

23:38.230 --> 23:39.070
Die arme CPU nicht.

23:39.490 --> 23:40.890
Also wieder falsch vorhergesagt.

23:41.050 --> 23:41.850
Zweiter Fehler schon.

23:42.330 --> 23:47.850
Jetzt sind wir in der Schleife drin, wo die Vorhersage auf Taken ist.

23:48.130 --> 23:50.330
Also der Zustand ist erst Weekly Not Taken.

23:50.630 --> 23:51.910
Vorhersage ist Taken.

23:51.910 --> 23:52.990
Hat er Recht gehabt.

23:53.510 --> 23:58.310
Damit ändert sich der Zustand wieder von Weekly Taken auf Strongly

23:58.310 --> 23:58.770
Taken.

23:59.150 --> 24:00.470
Vorhersage weiterhin Taken.

24:00.710 --> 24:02.170
Hat Recht, hat Recht, hat Recht, hat Recht, hat Recht.

24:02.370 --> 24:03.470
Also hier hat er alles Recht jetzt.

24:04.470 --> 24:07.490
Die letzte Iteration, die wird die Schleife verlassen.

24:08.030 --> 24:10.510
Die Vorhersage ist aber Strongly Taken.

24:10.550 --> 24:13.050
Weil die letzten so und so viele Sprünge waren ja alle Taken.

24:13.310 --> 24:13.830
Bedingten Sprünge.

24:14.510 --> 24:16.130
Das heißt, die Vorhersage ist falsch.

24:17.070 --> 24:19.210
Das lässt sich aber auch wirklich schwer verhindern.

24:19.330 --> 24:20.830
Auf gar keinen Fall mit diesen einfachen.

24:23.030 --> 24:26.910
Nächste Iteration, also erste Iteration der nächsten Schleife.

24:28.970 --> 24:31.450
Vorhersage ist, wir waren bei Taken, aber der Sprung wurde nicht

24:31.450 --> 24:31.670
genommen.

24:31.750 --> 24:34.030
Deswegen downgraden wir auf Weekly Taken.

24:34.650 --> 24:35.970
Zustand Weekly Taken.

24:36.490 --> 24:38.130
Vorhersage ist immer noch Taken.

24:38.990 --> 24:40.350
Und ja, der Sprung wird genommen.

24:40.450 --> 24:41.110
Hat er Recht gehabt.

24:41.430 --> 24:42.710
Er geht wieder auf Taken hoch.

24:42.810 --> 24:43.610
Bleibt auf Taken.

24:43.750 --> 24:45.490
Beim Verlassen der Schleife haben wir wieder einen Fehler.

24:45.730 --> 24:46.530
Also wieder einen falsch.

24:46.530 --> 24:51.490
In der Summe haben wir somit 16 von 20 richtige Vorhersagen.

24:52.050 --> 24:52.650
80%.

24:52.650 --> 24:55.370
Hatten wir das nicht gerade auch bei dem einen Prädiktor?

24:55.570 --> 24:57.290
Ja, genau das gleiche Ergebnis.

24:57.470 --> 24:58.450
Ziemlich blödes Beispiel.

24:59.310 --> 25:03.990
Aber, das kann besser funktionieren, wenn der Startzustand anders ist.

25:04.350 --> 25:08.210
Hier hätten wir angenommen, der Startzustand sei halt mal Not Taken.

25:08.410 --> 25:10.310
Der hat uns hier eben zwei Fehler reingehauen.

25:10.790 --> 25:13.650
Wenn wir das gleiche Beispiel angucken und einfach sagen, der

25:13.650 --> 25:15.010
Startzustand sei Taken.

25:15.010 --> 25:18.890
Dann hat er hier am Anfang immer richtig vorhergesagt und nur jeweils

25:18.890 --> 25:20.930
beim Verlassen der Schleife hat er einen Fehler gemacht.

25:21.430 --> 25:25.270
Und dann hat er 18 von 20 richtig vorhergesagt und somit 90%.

25:25.270 --> 25:26.910
Das ist schon mal ordentlich besser.

25:27.770 --> 25:30.890
Also man sieht, hängt irgendwie davon ab, wie wir jetzt gerade in die

25:30.890 --> 25:31.770
Schleife reinkommen.

25:32.090 --> 25:35.550
Manchmal ist es nur so gut wie der Einblickprädiktor, manchmal ist es

25:35.550 --> 25:37.830
aber auch deutlich besser als der Einblickprädiktor.

25:41.930 --> 25:43.950
Jetzt können wir uns noch ein anderes Beispiel anschauen.

25:43.950 --> 25:45.750
Immer noch mit dem gleichen Zweifelsprädiktor.

25:46.250 --> 25:49.230
Der hat nämlich noch eine... naja, Kinderkrankheit kann man nicht

25:49.230 --> 25:52.090
sagen, aber er hat eine Falle, in die man ihn locken kann.

25:52.490 --> 25:54.470
Und zwar bei alternierenden Sprüngen.

25:54.750 --> 25:58.250
Also Sprünge, die genau abwechselnd Taken und Not Taken sind.

25:58.650 --> 26:01.950
Wir könnten uns zum Beispiel vorstellen, dass ich eine Schleife habe

26:01.950 --> 26:04.190
und die Schleife wurde ausgerollt.

26:04.350 --> 26:09.190
So gesehen, der bedingte Sprung für die Schleifliteration ist weg.

26:09.190 --> 26:12.830
Aber in der Schleife innen drin hatte ich irgendwas stehen wie if

26:12.830 --> 26:16.470
Schleifenzähler Modulo 2 gleich 0 im Sinne von bei gerade

26:16.470 --> 26:19.690
Schleifenzähler macht das und bei ungerade Schleifenzähler macht das.

26:20.050 --> 26:23.550
Und da die Schleife immer plus 1 hochzählt, habe ich immer abwechselnd

26:23.550 --> 26:25.190
gerade, ungerade, gerade, ungerade.

26:25.270 --> 26:26.950
Der Sprung ist immer genau abwechselnd.

26:28.030 --> 26:33.310
Und wenn ich jetzt im Startzustand Weekly Not Taken anfange, also

26:33.310 --> 26:39.550
hier, und wenn der erste Sprung genommen wird, dann geht der genommen,

26:39.870 --> 26:44.850
wechselt er den Zustand auf einer Zeitachse, wechselt den Zustand von

26:44.850 --> 26:46.950
Weekly Not Taken auf Weekly Taken.

26:47.690 --> 26:51.610
Also falsche Vorhersage, weil er hat gesagt Not Taken, aber der Sprung

26:51.610 --> 26:52.190
war Taken.

26:52.190 --> 26:56.030
Für das nächste Mal sagt er vorher, der Sprung ist Taken, aber es war

26:56.030 --> 26:58.450
ja abwechselnd, der Sprung ist Not Taken.

26:58.770 --> 27:02.610
Also wieder falsche Vorhersage, wechselt in der Vorhersage auf Weekly

27:02.610 --> 27:04.870
Not Taken, hat er wieder genau falsch gelegen.

27:05.210 --> 27:11.590
Also der zittert zwischen den beiden Weekly Zuständen hin und her und

27:11.590 --> 27:16.130
sagt jedes Mal genau das falsche voraus, 0% Trefferquote.

27:16.130 --> 27:18.750
Und 0% ist echt schlechter als Raten.

27:19.270 --> 27:22.010
Also das ist eine Situation, die man auf jeden Fall mal irgendwie

27:22.010 --> 27:22.750
vermeiden muss.

27:22.990 --> 27:26.010
Da muss man sich irgendwas einfallen lassen, wie man das auffangen

27:26.010 --> 27:26.230
kann.

27:26.610 --> 27:28.410
Die Situation passiert nicht so wahnsinnig häufig.

27:28.570 --> 27:32.070
Ich habe hier relativ gezielt mit Weekly Not Taken und der erste

27:32.070 --> 27:33.330
Sprung sei Taken angefangen.

27:33.830 --> 27:36.230
Mit anderen Kombinationen rennt er nicht in diese Falle rein.

27:36.530 --> 27:38.170
Aber es gibt die Kombination halt eben.

27:38.250 --> 27:39.950
Und wenn sie mal passiert, dann ist es halt schmerzhaft.

27:41.390 --> 27:42.450
Was kann man da machen?

27:43.230 --> 27:45.890
Immer noch ein 2-Bit-Sprung-Vorhersage.

27:46.430 --> 27:49.330
Aber diesmal ist es kein saturierender Zähler mehr, sondern der hat

27:49.330 --> 27:49.990
eine höchste Rese.

27:50.290 --> 27:52.350
Also wenn wir mal kurz hin und her hüpfen zwischen den beiden Folien,

27:52.630 --> 27:55.330
ihr seht da ist quasi nur die Kanten hier sind geändert.

27:56.290 --> 27:59.230
Und zwar sind die Kanten so geändert, dass es halt keine Verbindung

27:59.230 --> 28:01.170
mehr gibt zwischen den beiden Weeklys.

28:01.330 --> 28:03.790
Und somit kann er auch nicht zwischen den beiden Weeklys hin und her

28:03.790 --> 28:04.230
flattern.

28:04.850 --> 28:12.010
Sondern, wenn ich einmal in dem Weekly angekommen bin und hier falsch

28:12.010 --> 28:15.330
vorhersage, also schauen wir mal, hier haben wir Taken als Vorhersage.

28:15.710 --> 28:20.130
Wenn jetzt Not Taken ausgeführt wird, dann gehe ich nicht wie zuvor in

28:20.130 --> 28:24.070
den anderen Weekly, sondern ich gehe gleich mal in den Strongly.

28:24.510 --> 28:29.110
Und immer wenn man so ein Flattern zwischen zwei Zuständen verhindert,

28:29.450 --> 28:30.430
das nennt man höchste Rese.

28:30.430 --> 28:32.430
Deswegen wird das hier eben höchste Rese Zähler genannt.

28:34.370 --> 28:38.730
Also ich gehe in den Strongly Not Taken und somit um auf die

28:38.730 --> 28:42.910
Vorhersage doch wieder Taken zurück zu kommen, muss auf jeden Fall

28:42.910 --> 28:46.270
jetzt zweimal ein Taken Sprung wirklich passieren.

28:46.510 --> 28:48.030
Damit ich wieder nach hier oben hinkomme.

28:48.830 --> 28:53.470
Das ist halt eben genau dafür da, um in diesem Beispiel nicht die 0%

28:53.470 --> 28:56.410
Fehler, also Vorhersagerichtigkeit zu haben.

28:56.410 --> 29:00.790
Sondern jetzt habe ich halt eben, naja, immerhin 50% Genauigkeit.

29:01.250 --> 29:03.790
Was immer noch nicht besser ist als ein statischer Prediktor, der

29:03.790 --> 29:05.650
konstant Not Taken vorhersagen würde.

29:05.890 --> 29:08.610
Aber es ist zumindest mal nicht schlechter als ein Einbildprediktor.

29:10.670 --> 29:13.730
Vielleicht am Beispiel einfach mal angenommen, ich würde anfangen...

29:13.730 --> 29:14.610
ach ist egal.

29:14.790 --> 29:15.750
Nehmen wir an, wir fangen hier an.

29:16.270 --> 29:18.630
Wenn jetzt der erste Sprung Taken ist, bin ich sowieso sicher.

29:18.770 --> 29:21.070
Also dann hätte ich quasi Taken, Not Taken, Taken, Not Taken würde ich

29:21.070 --> 29:24.370
hier hin und her iterieren und würde beides mal Taken vorhersagen.

29:24.370 --> 29:26.210
Damit bin ich in der Hälfte der Fälle richtig.

29:26.650 --> 29:29.250
Angenommen ich bin hier und der erste Sprung ist Not Taken, dann hätte

29:29.250 --> 29:32.810
ich quasi Not Taken, Taken, Not Taken, Not Taken, Not Taken würde ich

29:32.810 --> 29:33.870
hier hin und her iterieren.

29:34.170 --> 29:37.130
Die Vorhersage ist genau das Gegenteil, nehme ich Not Taken in beiden

29:37.130 --> 29:39.330
Fällen, trotzdem 50% richtig.

29:39.990 --> 29:45.170
Wenn ich hier anfange mit Taken, Not Taken, Taken, Not Taken würde ich

29:45.170 --> 29:46.190
quasi wieder hier oben iterieren.

29:46.590 --> 29:49.410
Wenn ich hier anfange mit Not Taken würde ich auch hier oben

29:49.410 --> 29:51.430
iterieren, dasselbe für hier unten.

29:51.430 --> 29:55.730
Also ich habe, egal wo ich anfange, egal wie der erste Sprung ist, 50%

29:55.730 --> 29:58.570
richtig vorhergesagt, was, naja, quasi Raten ist.

29:58.690 --> 29:59.750
Aber nicht schlechter als Raten.

30:04.790 --> 30:07.890
Jetzt wollte ich halt noch kurz andeuten, das geht genau in die Frage,

30:07.990 --> 30:11.750
die du hattest, wie dann die Besseren aussehen.

30:13.390 --> 30:19.670
Ja, zum Beispiel dieses Alternierende, das ist ja ein Muster, also

30:19.670 --> 30:21.650
wenn quasi immer gerade, ungerade, gerade, ungerade.

30:21.950 --> 30:24.630
Das ist ein Muster, wenn man sich das anguckt, dann kann man das

30:24.630 --> 30:24.970
sehen.

30:25.510 --> 30:28.090
Und wenn man ein Muster erkennen kann, dann kann man auch versuchen,

30:28.190 --> 30:29.770
es automatisch erkennbar zu machen.

30:30.330 --> 30:33.010
Und jetzt ohne irgendwie die Teilzeit zuzuhaben oder die Folien dafür,

30:33.110 --> 30:36.550
weil das ist, wie gesagt, weiterführende Vorlesung, nur mal andeuten,

30:36.650 --> 30:37.630
wie man das machen könnte.

30:38.070 --> 30:39.110
Und das wäre dann genau eine Sache.

30:40.070 --> 30:42.390
Es sind zwar noch, nee, das ist gar nicht die Richtung der Frage, es

30:42.390 --> 30:47.210
sind noch immer prinzipiell für jeden Sprung, sorry, ein Vorhersage

30:47.210 --> 30:52.150
-Ding global für das ganze System, aber ich kann versuchen, die

30:52.150 --> 30:54.290
zeitliche Historie mit zu berücksichtigen.

30:55.130 --> 30:59.390
Und zwar könnte ich sagen, die zeitliche Historie ist ja quasi nicht

30:59.390 --> 31:02.850
nur, wie der letzte Sprung genommen wurde, der entscheidet, in welchem

31:02.850 --> 31:05.330
Zustand ich jetzt bin, sondern ich könnte mir angucken, wie die

31:05.330 --> 31:08.250
letzten zwei, drei Sprünge ausgefallen sind.

31:08.610 --> 31:11.730
Und abhängig davon verschiedene Prädiktoren haben.

31:12.290 --> 31:12.790
Konkreter.

31:13.150 --> 31:15.850
Nehmen wir an, ich berücksichtige die letzten zwei Sprünge.

31:16.150 --> 31:19.770
Die letzten zwei Sprünge könnten vier verschiedene Ausgänge gehabt

31:19.770 --> 31:20.150
haben.

31:20.150 --> 31:29.050
Die könnten gehabt haben, taken, taken, taken, not taken, not taken,

31:29.450 --> 31:32.210
taken und not taken, not taken.

31:32.970 --> 31:36.030
Also das wären quasi, wenn wir hier noch ein Komma hinkriegen würden,

31:36.730 --> 31:42.090
die zeitlich letzten zwei Sprünge, was die für Ergebnisse, für

31:42.090 --> 31:44.370
Sprungergebnisse gehabt haben könnten.

31:44.370 --> 31:49.270
Und jetzt kann ich für jeden dieser vier Einträge so ein 2-Bit

31:49.270 --> 31:52.110
-Korrelation, also 2-Bit-Prädiktor haben, wie ich ihn hier stehen

31:52.110 --> 31:52.430
habe.

31:52.950 --> 31:55.550
Also nicht nur einen global, sondern vier global.

31:55.670 --> 31:58.310
Immer noch global für das ganze System, nicht pro Sprung, aber

31:58.310 --> 31:59.310
zumindest schon mal mehrere.

32:01.170 --> 32:04.390
Und jetzt kann man sich überlegen, für dieses Beispiel, mit dem immer

32:04.390 --> 32:10.950
abwechselnd, welche Prädiktoren kommen hier vor?

32:10.950 --> 32:13.130
Naja, es sind gerade die, wo es unterschiedlich ist.

32:13.510 --> 32:16.970
Hier wäre quasi der eine taken, not taken und hier ist der andere not

32:16.970 --> 32:17.570
taken, taken.

32:18.010 --> 32:21.110
Der hier wird quasi kaum benutzt werden, weil wenn ich immer

32:21.110 --> 32:24.070
abwechselnd taken, not taken, taken, not taken habe, dann kommt die

32:24.070 --> 32:27.030
Sequenz taken, taken, also der letzte Sprung taken, der vorletzte

32:27.030 --> 32:29.370
Sprung auch taken, die kommt in dieser Sequenz nicht vor.

32:29.850 --> 32:30.590
Genauso der hier.

32:30.910 --> 32:34.410
Dass die letzte und vorletzte beide not taken waren, kommt nicht vor.

32:34.410 --> 32:39.550
Es kommen quasi in dieser Annahme, immer abwechselnd, kommen nur die

32:39.550 --> 32:39.990
beiden vor.

32:40.170 --> 32:42.190
Taken, not taken und not taken, taken.

32:42.750 --> 32:45.270
Und was werden die Prädiktoren wohl vorhersagen?

32:46.170 --> 32:52.230
Wenn ich hier den taken, not taken 2-Bit-Prädiktor habe, da ich das

32:52.230 --> 32:55.670
Programm kenne, weiß ich ja, der nächste Sprung wird taken sein.

32:55.670 --> 32:59.590
Also egal in welchem Startzustand ich anfange, der wird sich Stück für

32:59.590 --> 33:03.490
Stück auf weakly taken, auf strongly taken ändern, der wird irgendwann

33:03.490 --> 33:05.610
taken vorhersagen als nächster Sprung.

33:06.230 --> 33:09.290
Genauso wenn die Zeit, wenn die Historie so aussieht, dass der

33:09.290 --> 33:12.730
vorletzte Sprung war not taken, der letzte Sprung war taken, dann weiß

33:12.730 --> 33:16.010
ich ja vom Programm, der nächste Sprung ist auch not taken.

33:16.010 --> 33:19.170
Also ich habe wieder meinen 2-Bit-Prädiktor hier drin, egal wo der

33:19.170 --> 33:22.450
anfängt, vielleicht fängt der auch bei taken an, aber es wird not

33:22.450 --> 33:26.470
taken, so gesehen würde er von taken auf weakly taken runtergehen,

33:26.770 --> 33:29.130
beim nächsten Mal, wenn der dran kommt, ist es wieder not taken, er

33:29.130 --> 33:34.890
würde immer weiter Richtung not taken runtergehen und irgendwann würde

33:34.890 --> 33:36.930
der auch einfach ein hartes not taken vorhersagen.

33:38.070 --> 33:43.470
Somit hätte ich jetzt mit dem Modell schon 100% richtig vorhergesagt

33:43.470 --> 33:47.530
für einfache Sequenzen, wo quasi immer alternierend was ist.

33:48.350 --> 33:51.930
Naja, und dann kommen die nächsten halt eben, die das Ganze nicht nur

33:51.930 --> 33:55.570
bei einer zeitlichen Abfolge machen, sondern die dann halt eben pro

33:55.570 --> 33:58.650
Sprung, also nicht für alle Sprünge, aber für viele Sprünge, pro

33:58.650 --> 34:02.530
Sprung einen Eintrag haben und dann nicht nur die zeitliche Abfolge

34:02.530 --> 34:06.170
des eigenen Sprunges angucken, sondern auch noch woher im

34:06.170 --> 34:08.210
Kontrollflussgraf kam ich eigentlich.

34:08.690 --> 34:10.330
Und das sind dann die, die wirklich benutzt werden.

34:10.730 --> 34:13.970
Aber da sind noch ein paar Ärgerlichkeiten drin, aber wie gesagt, die

34:13.970 --> 34:15.230
kommen jetzt nicht in dieser Vorlesung dran.

34:16.470 --> 34:20.510
Gut, also das waren mal die einfachen dynamischen und statischen

34:20.510 --> 34:21.710
Sprungvorhersagen.

34:22.170 --> 34:24.590
So, jetzt haben wir das Pipeline-Kapitel ja eigentlich, jetzt habe ich

34:24.590 --> 34:26.470
noch ein paar Beispiele für Pipelines, die wir uns auch mal kurz

34:26.470 --> 34:27.190
angucken können.

34:28.590 --> 34:32.430
Ja, die Pipelines heutzutage sind ja ziemlich hoch getaktet, durchaus

34:32.430 --> 34:33.930
im Gigahertz-Bereich.

34:34.230 --> 34:36.970
Ich meine, es gibt immer Ausnahmen, es gibt immer kleine Embedded

34:36.970 --> 34:39.330
-Systeme, weiß ich nicht, zum Beispiel so eine Uhr, was soll da ein

34:39.330 --> 34:41.230
Gigahertz -CPU drin, da gibt es was anderes für.

34:41.510 --> 34:45.350
Also für Notebooks, Desktop-PCs, Smartphones, irgendwie sowas, das ist

34:45.350 --> 34:46.450
alles im Gigahertz-Bereich.

34:46.990 --> 34:48.530
Ja, und Gigahertz ist ziemlich schnell.

34:48.650 --> 34:52.710
Gigahertz heißt eine Nanosekunde, also 1000 Picosekunden, 4 Gigahertz

34:52.710 --> 34:54.670
wären dann schon quasi nur noch eine Viertelnanosekunde.

34:55.050 --> 34:57.230
Das ist nicht lang, das ist wirklich nicht lang.

34:58.030 --> 34:59.310
Das wäre die Taktfrequenz.

34:59.530 --> 35:03.130
Und das heißt natürlich umgekehrt, bei den Taktfrequenzen kann ich pro

35:03.130 --> 35:04.670
Takt nicht so viel Arbeit machen.

35:05.070 --> 35:09.110
Also muss ich auch mehr Pipeline-Stufen haben, weil ich meine Arbeit

35:09.110 --> 35:12.290
jetzt auf mehr Stufen aufteilen muss, weil ich pro Stufe eventuell nur

35:12.290 --> 35:13.630
noch eine Viertelnanosekunde Zeit habe.

35:15.070 --> 35:16.870
Das ist das eine, was die halt eben haben.

35:17.350 --> 35:20.870
Und das andere ist, dass die halt eben zum einen dadurch, dass sie

35:20.870 --> 35:23.890
mehr Stufen haben und zum anderen dadurch, dass sie halt eben

35:23.890 --> 35:28.310
versuchen, Parallelität auszunutzen, viel mehr Befehle gleichzeitig in

35:28.310 --> 35:29.230
Bearbeitung haben.

35:29.310 --> 35:31.930
In Bearbeitung heißt hier In-Flight, wird das normalerweise genannt.

35:32.270 --> 35:34.890
Also die befinden sich irgendwo in der Pipeline drin.

35:35.510 --> 35:39.210
Und über 100 Befehle, die sich irgendwo in der Pipeline rumtummeln und

35:39.210 --> 35:41.490
irgendwas machen, das muss man erstmal managen können.

35:42.670 --> 35:44.170
Gucken wir uns noch Beispiele an.

35:44.470 --> 35:47.430
Den Pentium 4 hatten wir schon gesehen, also dieses Bild hatten wir

35:47.430 --> 35:48.730
schon gesehen vom Pentium 4.

35:50.310 --> 35:52.090
Vielleicht gucken wir uns einfach nur an.

35:53.590 --> 35:57.270
Ja, hier oben hätten wir zum Beispiel die dynamische Sprungvorhersage.

35:58.010 --> 36:01.250
Hier hätten wir jetzt nicht für jeden Sprung einen Eintrag, sondern

36:01.250 --> 36:06.330
4096 Einträge, also für 4096 zuletzt ausgeführte beobachtete Sprünge

36:06.330 --> 36:09.990
hätten wir quasi einen Eintrag da, wo dann jeweils ein Prädiktor drin

36:09.990 --> 36:12.230
sitzt, der dann die Vorhersage macht aus der History raus.

36:15.510 --> 36:18.470
Ja, den Rest hatten wir schon gesehen.

36:18.710 --> 36:20.890
Aber als kurze Wiederholung, wir hatten halt irgendwie, dass die

36:20.890 --> 36:28.790
Befehle aus dem Speicher über den L2-Cache in Befehls-Buffer kommen,

36:29.030 --> 36:30.970
dekodiert werden, das war dieses Micro-Code-Ding.

36:31.310 --> 36:33.590
Dann werden die Micro-Codes, hier ist ein Speicher für ganz viele

36:33.590 --> 36:35.390
Micro -Codes, zur Ausführung gebracht.

36:35.390 --> 36:38.590
Hier sind dann die verschiedenen Hardware-Einheiten und hier sind die

36:38.590 --> 36:40.330
Verteiler auf die verschiedenen Hardware-Einheiten.

36:41.670 --> 36:44.550
Und wenn jetzt gesagt ist, über 100 Befehle, die irgendwo sich

36:44.550 --> 36:46.990
tummeln, dann heißt das nicht über 100 Befehle, die sich in ALUs

36:46.990 --> 36:48.390
tummeln, also in den Recheneinheiten.

36:48.730 --> 36:51.170
Man kann sehen, hier sind gar nicht so viele Recheneinheiten, ja, bei

36:51.170 --> 36:51.930
Weitem keine 100.

36:52.950 --> 36:56.570
Aber es gibt halt eben eine Menge Befehle, die warten hier oben, ja,

36:56.630 --> 36:58.670
die warten hier oben, dass sie endlich drankommen.

36:58.770 --> 37:01.370
Die warten darauf, dass ihre Abhängigkeiten, ihre Datenabhängigkeiten

37:01.370 --> 37:03.550
erfüllt sind, damit sie dann loslegen können.

37:03.550 --> 37:08.150
Die, ja, die sitzen da und warten, sobald eine ALU frei wird, dann go

37:08.150 --> 37:08.510
for it.

37:09.590 --> 37:12.270
Die Idee ist halt eben immer, die ALUs beschäftigt zu halten.

37:12.350 --> 37:13.830
Die machen die Arbeit, die machen das Rechnen.

37:13.930 --> 37:16.450
Wenn die nichts zu tun haben, hat man irgendwie Potenzial verschenkt.

37:19.450 --> 37:24.850
Der Pentium 4 hat, je nachdem, welche Version man anguckt, eine ältere

37:24.850 --> 37:30.710
Version 20 Pipeline-Stufen, die späteren Version 31, 31 Pipeline

37:30.710 --> 37:31.090
-Stufen.

37:31.090 --> 37:36.970
Am Beispiel des kleineren mal die 20 Stufen hingemalt, jetzt mit

37:36.970 --> 37:37.910
Abkürzungen alles.

37:38.290 --> 37:40.790
Also da wird auf verschiedenen Stellen was geholt und ein bisschen

37:40.790 --> 37:43.450
umbenannt und in Warteschlangen eingereiht und da wird eine

37:43.450 --> 37:44.370
Reihenfolge festgelegt.

37:44.430 --> 37:47.070
Da wird alles mögliche gemacht und dann gibt es eine lustige kleine

37:47.070 --> 37:48.910
Stufe, execute.

37:49.650 --> 37:51.250
Stufe Nummer 17, execute.

37:51.510 --> 37:52.850
Das ist die einzige, die rechnet.

37:53.370 --> 37:57.430
Der Rest macht nur Verwaltung und sicherstellen, dass die Reihenfolgen

37:57.430 --> 37:58.830
eingehalten werden.

37:58.830 --> 38:00.590
Ein bisschen managen, verwalten.

38:01.030 --> 38:02.290
Eine einzige macht execute.

38:02.930 --> 38:06.350
Meine Lieblingsstufen sind 25, drive.

38:07.190 --> 38:10.130
Die Stufe macht nichts, die macht gar nichts.

38:10.470 --> 38:14.550
Die ist nur dafür da, ein Datum, was links unten im Chip ist, nach

38:14.550 --> 38:15.850
rechts oben im Chip zu kriegen.

38:16.250 --> 38:18.490
Aber in einer viertel Nanosekunde kommst du nicht weit.

38:18.730 --> 38:22.550
Also die Ladungsträger, die sind auch nicht unendlich schnell.

38:22.790 --> 38:25.630
Die müssen erst mal es schaffen, von der einen Ecke vom Chip zur

38:25.630 --> 38:26.450
anderen Ecke zu kommen.

38:26.450 --> 38:30.610
Also die Stufen sind nur dafür da, weil die Rechnung davor und die

38:30.610 --> 38:33.550
danach halt räumlich weit voneinander entfernt.

38:33.690 --> 38:37.790
Also räumlich weit entfernt im Sinne von mehreren Millimeter oder

38:37.790 --> 38:40.150
Mikrometer, sagen wir lieber, voneinander entfernt sind.

38:40.310 --> 38:42.710
Und dann dauert es halt einfach mal einen ganzen Takt, um die Daten

38:42.710 --> 38:43.830
von A nach B zu karren.

38:43.890 --> 38:45.030
Ohne irgendwas zu rechnen.

38:45.110 --> 38:46.170
Nur Datentransport.

38:46.690 --> 38:49.250
Und das ist halt eben, wo man sich anfängt zu überlegen, hat das jetzt

38:49.250 --> 38:52.330
wirklich was gebracht, das mit so vielen Stufen und so einer hohen

38:52.330 --> 38:55.070
Frequenz oder war das vielleicht doch eine dumme Idee.

38:55.070 --> 38:57.730
Da es den Pentium 4 nicht mehr gibt, war es wohl eine dumme Idee.

38:58.330 --> 39:00.510
Und die Nachfolger waren dann auch ganz anders aufgebaut.

39:00.890 --> 39:03.790
Die Nachfolger waren dann mit sehr, sehr viel langsameren Frequenzen.

39:04.250 --> 39:07.750
Und dass wir jetzt wieder bei 3, 4 Gigahertz angekommen sind, liegt

39:07.750 --> 39:10.710
einfach daran, dass die Herstellungstechnologie inzwischen so viel

39:10.710 --> 39:14.130
besser geworden ist, dass 3 und 4 Gigahertz, also dass man in der

39:14.130 --> 39:16.770
Viertelnanosekunde wirklich noch einiges an Rechnung hinkriegen kann.

39:16.890 --> 39:18.150
Was damals halt eben nicht der Fall war.

39:21.330 --> 39:24.690
Ja und man kann auch sehen, wenn ich so viele Stufen habe, 31 Stufen,

39:25.130 --> 39:28.710
wenn dann ein Sprung falsch vorhergesagt worden ist und die ganzen bis

39:28.710 --> 39:31.710
zu 31 Befehle oder noch mehr, die können ja irgendwo warten, einfach

39:31.710 --> 39:34.570
alle sinnlos sind, also gar nicht richtig sind, dann muss ich die alle

39:34.570 --> 39:35.410
wieder loswerden.

39:35.710 --> 39:38.090
Die sind dann nicht nur in der Pipeline, sondern die hängen auch in

39:38.090 --> 39:40.270
irgendwelchen Wartestellen, also wo sie halt auf ihre

39:40.270 --> 39:41.430
Datenabhängigkeiten warten.

39:41.770 --> 39:43.710
Da muss man denen sagen, die muss man erstmal wiederfinden.

39:43.710 --> 39:47.950
Man muss die ganzen Befehle wiederfinden, die quasi aufgrund von einer

39:47.950 --> 39:51.030
falschen Vorhersage in die Pipeline reingerutscht sind und dann muss

39:51.030 --> 39:52.090
man sie wieder rausschmeißen.

39:52.510 --> 39:55.930
Also das ist schon, deswegen sind Sprungvorhersagen für solche CPUs

39:55.930 --> 39:56.810
unglaublich wichtig.

39:57.370 --> 39:58.710
Also gute Sprungvorhersagen.

40:00.770 --> 40:02.650
Ja, einfach nur ein paar andere noch.

40:03.370 --> 40:06.250
CoAi, hat sich auch ein bisschen schon geändert, aber ist egal.

40:06.410 --> 40:08.390
Also im Prinzip sehen die alle ähnlich aus.

40:08.650 --> 40:11.210
Auch wieder hier eine Sprungvorhersage, die sagt, welcher Befehl soll

40:11.210 --> 40:12.130
als nächstes geholt werden.

40:12.130 --> 40:15.290
Der Befehl wird dann geholt, kommt in die ganzen Caches rein, kommt in

40:15.290 --> 40:17.250
die Ausführungswarteschlange.

40:18.770 --> 40:20.730
Und dann gibt es mehrere Decoder.

40:21.230 --> 40:25.710
Es war ja dieser CISC-Microcode-Befehlssatz.

40:26.150 --> 40:29.850
Also hier können mehrere Befehle gleichzeitig kodiert werden.

40:30.290 --> 40:32.190
Und der kann halt eben, da gibt es ein paar welche, die sind einfach,

40:32.290 --> 40:34.290
die können quasi nur einen Microbe pro Takt ausgeben.

40:34.450 --> 40:36.990
Und der Komplexe kann auch mehrere Microbes pro Takt generieren.

40:37.330 --> 40:38.710
Die kommen dann wieder in eine Warteschlange.

40:39.030 --> 40:40.270
Da gibt es wieder eine Warteschlange.

40:40.970 --> 40:44.230
Reorder-Buffer wäre quasi das, wo dann die Reihenfolge der Befehle...

40:44.230 --> 40:47.090
Also alles, was hier oben ist, wären noch die Befehle in der

40:47.090 --> 40:49.110
Reihenfolge, wie sie im Programm gestanden haben.

40:49.290 --> 40:51.490
Und alles unterhalb, dann werden sie halt umsortiert, wie es gerade

40:51.490 --> 40:51.750
passt.

40:52.470 --> 40:54.570
Dann werden sie auf die verschiedenen Einheiten verteilt.

40:54.750 --> 40:56.230
Irgendwann kommt es dann mal ins Rechnen.

40:56.630 --> 40:57.790
Und irgendwann...

40:58.230 --> 40:59.490
Da kann man die gar nicht sehen.

41:00.130 --> 41:03.050
Müsste das Ganze mal wieder in die Reihenfolge gebracht werden.

41:03.130 --> 41:07.270
Also ganz am Ende beim Fertigstellen, beim Gültigmachen sozusagen der

41:07.270 --> 41:10.970
Befehle, da wird es dann wieder in die Reihenfolge gehalten, wie der

41:10.970 --> 41:12.430
Programmierer es eigentlich haben wollte.

41:12.630 --> 41:15.230
Und zwischendurch durcheinander, so wie die Datenabhängigkeiten es

41:15.230 --> 41:15.950
gerade erlauben.

41:18.870 --> 41:22.730
Eine einfachere CPU hätte nicht so super erfolgreich gewesen, aber von

41:22.730 --> 41:26.210
der Idee her war halt eben der Plan, mal gucken, ob man nicht alles

41:26.210 --> 41:29.750
mit super viel Stromverbrauch und warm und kühlen müssen und all

41:29.750 --> 41:31.670
sowas, und man irgendwie ein bisschen einfacher das hinkriegen kann.

41:32.130 --> 41:33.150
Was sie einfach nur gemacht haben.

41:33.210 --> 41:33.990
Es sieht sehr ähnlich aus.

41:34.030 --> 41:36.090
Wenn ich mal hin und her wackele zwischen den Bildern...

41:36.090 --> 41:36.930
Ne, es passt nicht.

41:37.150 --> 41:38.510
Aber ich habe hier oben genau das gleiche.

41:38.590 --> 41:42.090
Das hier oben ist eigentlich genau das gleiche, nur alles dünner

41:42.090 --> 41:42.690
ausgelegt.

41:42.950 --> 41:47.110
Ich habe weniger Buffer, weniger Decoder, kleinere Queues, weniger

41:47.110 --> 41:48.830
Register, weniger Ausführungseinheiten.

41:49.230 --> 41:51.750
Also da ist einfach an vielen Stellen einfach ein paar weniger

41:51.750 --> 41:52.330
Einheiten.

41:52.810 --> 41:58.150
Aber vom Konzept her ist das immer noch eine super skalare

41:58.150 --> 42:00.030
Architektur, also mehrere Befehle gleichzeitig.

42:00.450 --> 42:01.410
Steht zufällig, wie viele?

42:01.650 --> 42:01.770
Ne.

42:01.770 --> 42:04.470
Die sich in der Pipeline befinden, aber jetzt in Order.

42:04.590 --> 42:07.390
Also jetzt wird quasi, wenn ein Befehl sagt, mö, du musst warten, dann

42:07.390 --> 42:08.170
wartet der auch.

42:08.870 --> 42:11.410
Das spart eine Menge von diesem Verwaltungs-Overhead.

42:13.570 --> 42:14.330
Gut, ja.

42:14.830 --> 42:18.730
Ein paar CPUs, ein paar Pipelines am Beispiel einfach mal angeguckt.

42:19.470 --> 42:25.050
Damit hätten wir das Pipelining-Kapitel fertig und können uns das

42:25.050 --> 42:26.090
nächste Kapitel angucken.

42:28.590 --> 42:32.670
Ja, das nächste Kapitel handelt jetzt erstmal von Speichern.

42:32.990 --> 42:35.570
Wir hatten jetzt quasi schon gesehen, sehen wir gleich nochmal, diese

42:35.570 --> 42:36.190
von Neumann-Architektur.

42:37.030 --> 42:39.450
Da hatten wir uns das Adresswerk angeschaut, das Rechenwerk

42:39.450 --> 42:41.210
angeschaut, das Steuerwerk angeschaut.

42:41.570 --> 42:44.170
Naja, und dann gibt es halt auch ein Speicherwerk, also das Ding, was

42:44.170 --> 42:46.650
irgendwie den Zugriff auf den Hauptspeicher macht.

42:47.150 --> 42:49.470
Da gibt es dann auch wieder die Beschleunigungsdinger, Caches, aber

42:49.470 --> 42:50.110
die kommen noch später.

42:50.990 --> 42:54.270
Jetzt schauen wir erstmal an, was ist dieser Speicher überhaupt, wie

42:54.270 --> 42:56.670
sieht der aus, wie funktioniert der, wie kann man auf den zugreifen.

43:00.720 --> 43:03.720
Der Speicher ist immer wichtiger geworden in der letzten Zeit.

43:04.100 --> 43:06.180
Naja, in der letzten Zeit, in den letzten Jahrzehnten eigentlich

43:06.180 --> 43:06.500
schon.

43:06.860 --> 43:11.400
Was einfach daran liegt, dass diese Lücke, die hier aufgezeigt ist,

43:11.480 --> 43:12.460
immer weiter aufgeht.

43:13.260 --> 43:17.700
Wir haben hier auf einer Zeitachse normiert auf 1980.

43:17.700 --> 43:22.400
Also im Sinne von, alle Zahlen, die hier stehen, sind relativ zu 1980.

43:22.640 --> 43:24.600
1980 ist definiert worden als 1x.

43:25.300 --> 43:29.260
Und zwar einmal für den Prozessor, von mir aus irgendeine Art von

43:29.260 --> 43:32.300
Geschwindigkeit, also Verarbeitungsgeschwindigkeit, so was wie, weiß

43:32.300 --> 43:36.040
ich nicht, Integra-Arithmetik-Operationen pro Sekunde.

43:36.180 --> 43:38.460
Irgendeine Metrik für Verarbeitungsgeschwindigkeit.

43:39.040 --> 43:43.740
Hier 1x und hier hundertmal schneller als damals, hier tausendmal

43:43.740 --> 43:44.480
schneller als damals.

43:44.480 --> 43:46.280
Was ja nicht schlecht ist.

43:46.420 --> 43:48.020
Tausendmal schneller ist gar nicht so schlecht.

43:48.900 --> 43:52.660
Wohingegen der Hauptspeicher, auch wieder normiert auf 1980, jetzt ist

43:52.660 --> 43:53.620
die Metrik halt eine andere.

43:53.780 --> 43:55.440
Ich meine, der macht keine Arithmetik-Operationen.

43:55.640 --> 43:59.340
Der macht dann irgendwie sowas wie Megabyte pro Sekunde, die er

43:59.340 --> 44:03.380
heranschaffen kann, also Durchsatz oder vielleicht Latenz, so Takte,

44:03.560 --> 44:05.180
um einen Zugriff zu machen oder sowas.

44:05.280 --> 44:07.020
Also so eine Geschwindigkeitsmetrik für Speicher.

44:07.720 --> 44:12.320
1x war 1980 und bei 10x sind wir bald.

44:13.060 --> 44:17.720
Also das wächst auch, aber dramatisch langsamer.

44:18.260 --> 44:22.600
Genau genommen haben wir von Moore's Law kennt man Verdopplung alle so

44:22.600 --> 44:24.700
12, 18, 24 Monate.

44:24.860 --> 44:27.360
Hier waren es halt eben mal 18 Monate.

44:28.100 --> 44:30.900
Hauptspeicher hat man eine Verdopplung alle, naja, so 10 Jahre.

44:31.060 --> 44:32.200
Kann man nicht so genau sagen.

44:32.300 --> 44:33.880
Ist eine ziemlich lange Zeit aus Sicht eines Menschen.

44:35.180 --> 44:36.680
Also deutlich langsamer.

44:36.680 --> 44:40.400
Und das heißt, diese Lücke von den Geschwindigkeiten, die wird größer

44:40.400 --> 44:42.240
und zwar um ungefähr 50% pro Jahr.

44:42.340 --> 44:43.600
Auch ein exponentielles Wachstum also.

44:45.060 --> 44:50.180
Und das heißt im Wesentlichen, die CPUs, die könnten immer schneller

44:50.180 --> 44:53.940
arbeiten, wenn man ihnen die Daten dafür geben würde.

44:54.400 --> 44:58.360
Sie sind quasi einen Großteil der Zeit beschäftigt mit Warten auf

44:58.360 --> 44:58.680
Daten.

44:59.220 --> 45:00.320
Das kann es ja irgendwie nicht bringen.

45:00.460 --> 45:01.400
Also da muss man irgendwie was machen.

45:01.820 --> 45:03.660
Naja, die Lösung dafür sind die Caches.

45:04.520 --> 45:07.040
Aber vorher schauen wir uns an, wie sehen diese Speicher überhaupt

45:07.040 --> 45:07.340
aus.

45:07.900 --> 45:10.240
Was müssen die eigentlich machen in ihrer Zeit, die sie so zu tun

45:10.240 --> 45:10.440
haben.

45:12.200 --> 45:15.820
So, wir hatten schon, also gesagt, wir haben irgendwie CPUs gesehen.

45:16.400 --> 45:18.040
Und jetzt gibt es halt eben auch noch Speicher.

45:18.120 --> 45:20.900
Die hängen irgendwie an einem Verbindungsnetzwerk, sind die irgendwie

45:20.900 --> 45:21.420
verbunden.

45:21.820 --> 45:26.560
Und dann gibt es auch noch ein Ausgabegeräte, die am gleichen Bus

45:26.560 --> 45:27.920
hängen, wo es dann normalerweise geht.

45:28.200 --> 45:30.020
Je nach Adresse, die die CPU fragt.

45:30.120 --> 45:32.140
Wenn sie nach der einen Adresse fragt, landet sie im Speicher.

45:32.140 --> 45:35.500
Und wenn sie nach einer anderen Adresse fragt, landet sie auf

45:35.500 --> 45:36.560
irgendeinem Ausgabegerät.

45:36.600 --> 45:38.180
Von mir aus eine Ethernet-Card oder sowas.

45:38.380 --> 45:39.960
Da müssen ja auch mal Daten hingeschoben werden.

45:43.140 --> 45:47.100
Gut, Hauptspeicher, Memory, Main-Memory nennt man ja auch

45:47.100 --> 45:47.940
Hauptspeicher halt eben.

45:48.620 --> 45:53.120
Die Idee vom Hauptspeicher ist, dass man jeden Eintrag im

45:53.120 --> 45:57.280
Hauptspeicher nach Bedarf jederzeit zugreifen kann.

46:00.460 --> 46:03.560
Jederzeit, sofort, ist jetzt meiner Meinung nach nicht so ganz die

46:03.560 --> 46:04.980
Definition von Random Access.

46:05.720 --> 46:09.580
Random Access meint eigentlich eher... naja, man kann es übersetzen.

46:09.920 --> 46:14.740
Aber was gemeint ist, es gibt Speicher, bei denen sind die Daten zwar

46:14.740 --> 46:18.800
vorhanden, aber ich kann den Speicher nicht sagen, gib mir mal dieses

46:18.800 --> 46:19.400
Byte dort.

46:19.760 --> 46:20.180
Geht nicht.

46:20.560 --> 46:24.760
Sondern ich muss dem Speicher erst sagen, öffne mal folgende Seite.

46:24.760 --> 46:28.440
Und nachdem du das gemacht hast, innerhalb von der Seite, gib mir das

46:28.440 --> 46:29.240
so und so vielte Byte.

46:29.540 --> 46:31.280
Und erst dann kann ich das Byte zugreifen.

46:31.840 --> 46:37.340
Es gibt auch Speicher, USB-Sticks, wo ich nicht nach Belieben einfach

46:37.340 --> 46:40.020
irgendwas, ein Byte löschen kann oder überschreiben kann.

46:40.160 --> 46:43.100
Sondern die sind auch wieder blockweise bearbeitbar.

46:43.400 --> 46:47.640
Wenn ich ein einzelnes Byte ändern will, dann heißt das, nimm mal den

46:47.640 --> 46:51.060
Block, 4 Kilobyte, und kopiere den von A nach B.

46:51.060 --> 46:54.020
Und während du ihn kopierst, sag mal, dieses eine Byte soll einen

46:54.020 --> 46:54.800
anderen Wert haben.

46:55.080 --> 46:57.060
Und nachdem du es kopiert hast, sagt er, der alte Block ist nicht mehr

46:57.060 --> 46:58.520
benötigt, der ist ungültig.

46:59.860 --> 47:01.300
Das ist hier eben nicht gemeint.

47:01.360 --> 47:04.440
Hier ist gemeint ein Speicher, wo ich auf jedes Byte einzeln zugreifen

47:04.440 --> 47:05.500
kann, so wie ich möchte.

47:05.660 --> 47:08.660
Lesen, schreiben, wann auch immer ich möchte, ohne irgendwelche

47:08.660 --> 47:11.240
Abhängigkeiten berücksichtigen zu müssen.

47:11.580 --> 47:15.980
Also ich kann nicht zufällig zugreifen, sondern ich kann so wie ich

47:15.980 --> 47:19.840
will, das durchaus eine Zufallssequenz sein dürfte, so wie ich will,

47:20.160 --> 47:22.580
zugreifen auf den Speicher RAM.

47:24.840 --> 47:27.500
Wohingegen das andere Wort ROM, was man immer hört, hat etwas ganz

47:27.500 --> 47:29.000
anderes zu bedeuten, das ist Read Only.

47:29.160 --> 47:31.180
Das kann man nur lesen, das kann man nicht schreiben.

47:31.720 --> 47:34.300
Und RAM heißt Random Access, ich kann lesen, schreiben, jede Adresse,

47:34.440 --> 47:34.820
wie ich möchte.

47:37.580 --> 47:41.540
Von Neumann hatten wir schon gesehen, wir hatten Steuerwerk gesehen,

47:41.660 --> 47:44.240
Rechenwerk, Verbindungsnetzwerk, und jetzt sind wir irgendwie im

47:44.240 --> 47:47.360
Hauptspeicher gelandet, wo man eben die Daten ablegen muss.

47:48.840 --> 47:50.400
Wie sieht so ein Speicher aus?

47:51.180 --> 47:52.760
Der sieht grob so aus.

47:53.220 --> 47:55.200
Wir haben jetzt mal dieses Verbindungsnetzwerk einfach weg

47:55.200 --> 47:57.640
abstrahiert, hier gibt es einfach eine Verbindung zwischen CPU und

47:57.640 --> 47:57.980
Speicher.

47:58.060 --> 48:01.120
Wie die aussieht, mir völlig egal, Hauptsache Adressen, Daten, Befehle

48:01.120 --> 48:01.720
kommen hier an.

48:02.560 --> 48:05.560
So, jetzt habe ich im Speicher innen drin die eigentliche

48:05.560 --> 48:07.520
Speichermatrix, das ist dieses Ding hier.

48:08.380 --> 48:13.120
Die Speichermatrix besteht aus Zeilen und jede Zeile besteht aus

48:13.120 --> 48:13.520
Speicherelementen.

48:14.340 --> 48:15.100
Element ist einfach ein Bit.

48:15.400 --> 48:18.400
Ein 1-Bit-großer Speicher, das wäre ein Speicherelement.

48:19.040 --> 48:21.960
Sagt jetzt noch nichts über Technologie, könnte ein SRAM, ein DRAM,

48:22.020 --> 48:24.700
ein was auch immer Speicher sein, egal was, ist auf jeden Fall erstmal

48:24.700 --> 48:26.400
ein 1-Bit-großes Speicherelement.

48:28.200 --> 48:32.780
Und jetzt habe ich hier vorne dran einen Adressdecoder und unten dran

48:32.780 --> 48:34.380
noch eine Spaltenauswahl.

48:34.380 --> 48:38.140
Jetzt mal kurz, das kommt später nochmal, an einem Beispiel hier, wie

48:38.140 --> 48:39.620
ein Zugriff funktionieren würde.

48:42.360 --> 48:48.520
Ich habe die Adresse, lege ein Teil von der Adresse, nicht alles, an

48:48.520 --> 48:51.880
den Adressdecoder dran und der Adressdecoder macht jetzt was?

48:52.200 --> 48:55.940
Der Adressdecoder ist hier gemalt wie ein Demultiplexer und genau das

48:55.940 --> 48:56.440
ist er auch.

48:56.820 --> 48:58.440
Was war doch gleich ein Demultiplexer?

48:58.440 --> 49:08.460
Ein Demultiplexer war dieses Ding, wo mehrere Inputs reingehen und

49:08.460 --> 49:12.020
dann gibt es von mir aus ein n-bitiges Steuersignal, wenn hier 2 hoch

49:12.020 --> 49:15.900
n Inputs sind und der lässt einen von diesen 2 hoch n raus.

49:16.080 --> 49:20.440
Also das Steuersignal wählt aus, welcher an den Output rauskommt.

49:21.640 --> 49:24.920
Demux ist das Gegenteil, also quasi gemalt wie hier.

49:29.740 --> 49:34.460
Ich habe quasi mein Steuersignal irgendwo anliegen, das kommt jetzt

49:34.460 --> 49:35.560
hier von links rein, aber ist egal.

49:35.900 --> 49:39.720
Eigentlich hätte ich hier ein ein-bitiges Inputsignal und hätte hier

49:39.720 --> 49:44.700
weiterhin mein Steuersignal und habe mehrere Outputs.

49:45.720 --> 49:49.260
Nehme ich wieder 2 hoch so viele Bits wie ich hier habe.

49:49.900 --> 49:54.000
Und jetzt wird einfach gesagt, der Input wird auf genau einen der

49:54.000 --> 49:57.560
Outputs durchgeschaltet und alle anderen Outputs sind 0.

49:57.840 --> 49:59.620
So ist der Demux definiert.

50:00.560 --> 50:03.800
Jetzt wird hier einfach gesagt, den Input legen wir hier konstant auf

50:03.800 --> 50:05.280
1, so gesehen können wir den weglassen.

50:05.960 --> 50:10.740
Das heißt, in der Ausgabe ist genau ein Bit eine 1 und alle anderen

50:10.740 --> 50:11.520
sind 0.

50:12.160 --> 50:15.580
Je nachdem, welche Ausgabezeile aktiviert wurde.

50:15.920 --> 50:21.040
Und die Adresse, die hier ankommt, die sagt jetzt quasi, welche eine

50:21.040 --> 50:26.760
einzelne Leitung von der Ausgabe aktiviert, zugegriffen, angesprochen

50:26.760 --> 50:27.540
werden soll.

50:27.760 --> 50:29.780
Nämlich die eine Zeile, die eine 1 bekommt.

50:30.320 --> 50:32.860
Wie das jetzt hier innen drin funktioniert, das ignorieren wir mal

50:32.860 --> 50:33.580
geschickt für den Moment.

50:33.920 --> 50:38.620
Aber die eine Zeile, die hier angesprochen wird, die eine Zeile wird

50:38.620 --> 50:39.960
dann ausgelesen.

50:39.960 --> 50:44.920
Im Sinne von, es gibt hier irgendeinen Verbindungsbus, der hier runter

50:44.920 --> 50:46.060
geht bis zum Ausgang.

50:46.600 --> 50:51.260
Und auf diesen Verbindungsbus könnte entweder dieses Speicherelement

50:51.260 --> 50:54.620
auf den Bus hier gehen oder dieses Speicherelement oder dieses

50:54.620 --> 50:56.040
Speicherelement oder dieses Speicherelement.

50:56.200 --> 50:58.660
Halt eben höchstens 1, sonst Kurzschlussgefahr.

50:59.400 --> 51:03.260
Und welches genau eine, das macht der Adressdecoder oder auch

51:03.260 --> 51:04.160
Zeilendecoder.

51:04.300 --> 51:08.720
Der aktiviert eine Zeile, deren Inhalt wird ausgegeben nach unten.

51:08.720 --> 51:12.860
So, jetzt purzelt hier unten die Zeile rein und die Zeile hat eine

51:12.860 --> 51:13.580
gewisse Größe.

51:13.800 --> 51:14.440
Welche Größe?

51:14.720 --> 51:15.880
Abhängig von dem Speicher.

51:16.140 --> 51:17.400
Also von der Speichermatrix.

51:17.840 --> 51:20.600
Das könnten zum Beispiel auch mal 1024 Bit sein.

51:21.100 --> 51:25.120
Und von diesen 1024 Bit wollte ich aber eigentlich vielleicht nur ein

51:25.120 --> 51:28.100
Byte haben oder ein 32 Bit Wort oder irgendwas.

51:28.240 --> 51:30.520
Ich wollte nur ein Teil von dieser ganzen Zeile haben.

51:30.960 --> 51:31.960
Und welcher Teil?

51:32.540 --> 51:34.100
Das sagt die Spaltenauswahl.

51:35.040 --> 51:38.660
Da wird jetzt quasi der Rest von der Adresse genommen, genau genommen

51:38.660 --> 51:39.960
die Least Significant Bits.

51:40.420 --> 51:44.320
Die werden genommen, um jetzt zu sagen, welche Bits genau an den

51:44.320 --> 51:46.880
Ausgang ausgegeben werden sollen und welche nicht.

51:47.280 --> 51:49.200
Dafür ist die Spaltenauswahl unten zuständig.

51:49.600 --> 51:53.380
Und damit könnte ich quasi von den 1024 Bits ein Byte hier unten

51:53.380 --> 51:57.380
ausgeben oder ein anderes Byte oder 16 Bit irgendwo kann ich damit

51:57.380 --> 51:57.820
ausgeben.

51:59.660 --> 52:00.060
Okay.

52:00.060 --> 52:03.580
Und ausgeben habe ich jetzt gesagt, weil ich immer an Lesen denke,

52:03.740 --> 52:05.340
aber es ist prinzipiell Lesen und Schreiben.

52:05.460 --> 52:07.680
Also hier gehen die Pfeile nur in eine Richtung, weil das quasi nur

52:07.680 --> 52:08.960
die Aktivierung der Zeile ist.

52:09.360 --> 52:11.360
Wohingegen hier gehen die Pfeile alle in beide Richtungen.

52:11.680 --> 52:14.420
Beim Lesen werden die quasi auf den Bus gegeben und putzeln hier unten

52:14.420 --> 52:14.760
raus.

52:14.960 --> 52:16.540
Der wählt dann aus und dann werden sie ausgegeben.

52:16.980 --> 52:19.840
Schreiben wäre hingegen, die Daten kommen von außen rein.

52:19.980 --> 52:22.320
Also das ist dann offenbar kein Reiner-Mux-Demux mehr, das geht in

52:22.320 --> 52:22.800
beide Richtungen.

52:22.800 --> 52:28.680
Daten kommen von außen rein und werden dann in die richtige Spalte

52:28.680 --> 52:32.860
geschrieben und haben dann Auswirkungen auf die eine Zeile, die jetzt

52:32.860 --> 52:35.320
hier aktiviert worden ist, deren Werte können dann überschrieben

52:35.320 --> 52:35.640
werden.

52:36.800 --> 52:40.000
Das Ganze wird gesteuert von diesen Befehlen.

52:40.180 --> 52:44.420
Das heißt, der Datenteil müsste auf jeden Fall mal irgendwie hier

52:44.420 --> 52:47.580
unten angeschlossen werden, beidseitig.

52:47.580 --> 52:50.180
Wohingegen die Befehle dann wirklich irgendwo hier hingehen.

52:50.240 --> 52:54.260
Die Befehle würden dann quasi sagen, ob hier schreiben oder lesen

52:54.260 --> 52:57.120
zugegriffen werden soll, ob der Chip überhaupt gemeint war.

52:57.480 --> 53:00.080
Also kann ja sein, dass hier irgendeine Adresse anliegt, aber es ist

53:00.080 --> 53:03.800
an dem Systembus vielleicht gar nicht der Speicher gemeint gewesen,

53:03.880 --> 53:04.740
sondern irgendwas anderes.

53:04.980 --> 53:07.140
Dann darf der Chip halt eben der Speicher hier halt überhaupt nichts

53:07.140 --> 53:07.420
machen.

53:07.800 --> 53:10.540
Solche Sachen würden bei den Befehlen halt eben dann alles drin

53:10.540 --> 53:10.780
stehen.

53:13.780 --> 53:18.000
Und natürlich muss da auch drin stehen, hier ist ja quasi nur die

53:18.000 --> 53:19.840
Startadresse von dem Zugriff.

53:19.960 --> 53:22.720
Also das unterste Byte, auf das zugegriffen werden soll.

53:23.040 --> 53:25.520
Aber da muss im Befehl halt auch noch drin stehen, soll ein Byte

53:25.520 --> 53:28.480
zugegriffen werden oder zwei Byte oder vier Byte oder wie viel soll

53:28.480 --> 53:29.980
eigentlich jetzt gelesen oder geschrieben werden.

53:30.040 --> 53:31.300
Das kann die Adresse ja nicht sagen.

53:31.400 --> 53:32.800
Die Adresse sagt nur, wo es anfängt.

53:33.180 --> 53:36.000
Die Befehle müssen dann noch sagen, wie viel zugegriffen werden soll.

53:37.260 --> 53:41.780
So würde im Allgemeinen quasi jeder Speicher intern aufgebaut sein.

53:42.900 --> 53:47.260
Heißt insbesondere, man denkt sich immer, der Speicher wäre so ein 32

53:47.260 --> 53:48.360
-Bit breites Ding.

53:48.540 --> 53:49.440
Ist er meistens nicht.

53:49.820 --> 53:54.220
Ich greife zwar 32-Bitig auf den Speicher zu, weil mein Datenbus 32

53:54.220 --> 53:57.860
-Bit groß ist, aber der Speicher eigentlich ist selber meist so

53:57.860 --> 54:01.900
aufgebaut, dass quasi die Anzahl Zeilen, Anzahl Spalten möglichst eine

54:01.900 --> 54:05.080
gleich große Zahl sind, weil es sich rein physikalisch als Quadrat

54:05.080 --> 54:07.480
oder annähernd Quadrat besser herstellen lässt.

54:07.940 --> 54:11.060
Auch wenn ich dann nur 32-Bitig oder 34-Bitig darauf zugreife.

54:11.460 --> 54:13.260
Weil dann der Datenbus einfach nur so klein ist.

54:15.660 --> 54:17.100
Ja, ein paar Begriffe.

54:17.420 --> 54:19.000
Speicherelement hatten wir gerade gesehen.

54:20.080 --> 54:21.960
Speicherelement, Speicherzeile, Speicherwort.

54:23.160 --> 54:26.720
Speicherelement war das hier, Speicherzeile war das hier.

54:27.380 --> 54:31.220
Speicherwort wäre dann quasi ein von mir aus 32-Bit-Wort oder im

54:31.220 --> 54:34.940
Allgemeinen halt eben die Größe der Datenbus halt eben ist.

54:35.020 --> 54:37.900
Also die Speicherwortbreite ist für gewöhnlich genau das, was die

54:37.900 --> 54:39.460
Datenbusbreite ist.

54:42.320 --> 54:44.480
Wahlfreier Zugriff hatten wir schon gesehen, also Random Access.

54:44.640 --> 54:48.960
Ich kann jedes beliebige Element sogar einzeln zugreifen.

54:48.960 --> 54:52.260
Also ich kann jede beliebige Zeile aktivieren und aus der Zeile kann

54:52.260 --> 54:56.800
ich jede beliebiges Byte einzeln rausholen oder überschreiben.

54:57.000 --> 54:58.020
Je nachdem, was ich machen möchte.

54:58.640 --> 55:06.380
Hier noch dieses 1 aus n hier, um den Namen mal zu erwähnen.

55:06.820 --> 55:14.200
1 aus n heißt halt einfach, ich habe einen n-Bit-breiten Bitvektor,

55:14.520 --> 55:18.620
von dem genau ein Bit den Wert 1 hat und alle anderen den Wert 0.

55:18.620 --> 55:21.360
Das ist genau das, was der Adressdecoder tut.

55:21.740 --> 55:24.080
Eine von den Zeilen wird aktiviert, genau eine.

55:24.380 --> 55:28.280
Also eine aus diesen n Zeilen wird aktiviert und das ist halt eben so

55:28.280 --> 55:29.520
ein 1 aus n Code.

55:35.670 --> 55:36.230
Speicherorganisation.

55:36.650 --> 55:40.290
Das beschreibt, wie groß diese Speichermatrix, das Speicherarray ist.

55:40.750 --> 55:43.230
Also Anzahl Zeilen, Anzahl Spalten.

55:43.230 --> 55:48.090
Und das Array Matrix wäre dann halt eben n mal m Speicherelemente und

55:48.090 --> 55:50.930
normalerweise ist jedes Speicherelement ein Bit, also n mal m Bit.

55:51.210 --> 55:54.590
Das wäre gleichzeitig auch die Speicherkapazität.

55:55.270 --> 55:58.830
Der Unterschied ist, bei der Speicherkapazität interessiert mich nur,

55:59.570 --> 56:01.370
wieviel Bit ist der Speicher wirklich groß.

56:02.110 --> 56:04.910
Also das Ergebnis der Multiplikation interessiert mich.

56:04.910 --> 56:07.850
Wohingegen bei der Organisation interessiert mich halt eben auch,

56:08.170 --> 56:09.950
wieviel Zeilen gibt es, wieviel Spalten gibt es.

56:10.030 --> 56:12.790
Also die Werte von n und m interessieren mich.

56:13.290 --> 56:16.050
Und das Ergebnis der Multiplikation ist dann die Kapazität.

56:17.150 --> 56:20.210
Zum Beispiel hätten wir hier 4k mal 8.

56:20.390 --> 56:26.770
Soll heißen, wir hätten einen Speicher mit 4096 Zeilen, weil die halt

56:26.770 --> 56:29.610
4096 Adresseingänge hat, die Matrix.

56:29.790 --> 56:34.070
Also dieses Ding hier, dann 4096 Einträge, 4096 Zeilen.

56:34.070 --> 56:37.890
Und jede Zeile enthält 8 Bit Daten.

56:39.850 --> 56:43.990
Anderes Beispiel, ein Speicher, der zum Beispiel 16 Megabit groß ist,

56:44.290 --> 56:48.930
könnte organisiert sein als 4 Millionen Zeilen, in jeder Zeile stehen

56:48.930 --> 56:49.810
nur 4 Bit drin.

56:50.230 --> 56:52.910
Oder 2 Millionen Zeilen, in jeder Zeile stehen 8 Bit.

56:53.050 --> 56:54.690
Oder eine Million mit jeweils 16 Bit.

56:55.130 --> 56:57.630
Oder 500.000 mit 32 Bit.

56:57.710 --> 57:00.230
Oder 52.000 mit 44 Bit und so weiter.

57:00.350 --> 57:02.570
Also beliebige Aufteilung eigentlich.

57:03.550 --> 57:06.890
Und wie gesagt, das ist jetzt nicht gerade die üblichste Organisation.

57:07.830 --> 57:08.830
Eher quadratisch.

57:14.870 --> 57:17.850
Begriffe Arbeitsgeschwindigkeit muss man unterscheiden.

57:18.050 --> 57:22.590
Also erstmal, Geschwindigkeit ist hier im Sinne von Latenz, von Takt

57:22.590 --> 57:23.370
zu verstehen.

57:25.890 --> 57:29.210
Durchsatz im Sinne von Megabyte pro Sekunde, wieviel Daten können

57:29.210 --> 57:31.670
wirklich rausgeschaufelt oder reingeschaufelt werden.

57:31.670 --> 57:34.850
Hier sind Latenzen, also Verzögerungen gemeint.

57:35.310 --> 57:38.950
Einmal die Zugriffszeit wäre im Beispiel des Lesens.

57:39.350 --> 57:40.830
Ich lege die Adresse an.

57:41.250 --> 57:45.690
Nach wieviel Zeit, Nanosekunden, bekomme ich die Daten, die ich lesen

57:45.690 --> 57:45.990
wollte.

57:46.370 --> 57:48.330
Wie lang ist die Verzögerung dazwischen.

57:48.990 --> 57:51.370
Und die Zykluszeit, wir sehen nachher noch Beispiele an Bildern.

57:51.690 --> 57:54.550
Die Zykluszeit ist, ich lege eine Adresse an.

57:55.310 --> 57:59.050
Wann darf ich die nächste Adresse anlegen, für den nächsten Zugriff.

57:59.050 --> 58:04.650
Es ist klar, ich muss natürlich erst die Zugriffszeit abwarten, bis

58:04.650 --> 58:05.290
das erledigt ist.

58:05.370 --> 58:07.150
Und danach kann ich die nächste Adresse anlegen.

58:07.550 --> 58:09.510
Es sei denn, das Ding ist intern gepipelined.

58:09.770 --> 58:11.270
Dann könnte das auch irgendwie umgekehrt sein.

58:11.350 --> 58:12.190
Ist es aber meistens nicht.

58:14.490 --> 58:18.490
Also, bei einer einzelnen Speichermatrix ist das meistens nicht.

58:18.610 --> 58:21.610
Und große Speicher werden dann zusammengesetzt, indem man mehrere von

58:21.610 --> 58:22.650
diesen Speichermatrixen hat.

58:22.730 --> 58:24.090
Und dann ist es dann meistens gepipelined.

58:24.930 --> 58:26.730
Aber hier so bei einfachen Arrays nicht.

58:27.910 --> 58:30.510
Das Ganze als Bild nochmal hingeschrieben.

58:31.090 --> 58:31.570
Malt.

58:32.150 --> 58:37.350
Wir hätten quasi auf einer Zeitachse irgendwann eine Adresse.

58:37.870 --> 58:41.210
Ab hier ist sie quasi gültig und kann vom Speicher übernommen werden.

58:41.870 --> 58:43.810
Und dann dauert es beim Speicher, stellen wir uns mal einen

58:43.810 --> 58:48.810
Lesezugriff vor, dauert es eine gewisse Weile, bis der Speicher die

58:48.810 --> 58:50.130
Daten wirklich ausgibt.

58:50.310 --> 58:52.830
Also hier zwischendurch liegen ja auch irgendwelche Einsen und Nullen

58:52.830 --> 58:52.950
an.

58:53.030 --> 58:54.830
Ja, keine Ahnung, irgendwas wird da schon anliegen.

58:54.830 --> 58:59.730
Aber die gültigen Daten, die zu der Adresse gehören, die würden halt

58:59.730 --> 59:03.370
erst nach der T-Zugriffszeit anliegen.

59:03.870 --> 59:07.890
Und Zykluszeit ist halt eben genau, ab wann kann ich die nächste, hier

59:07.890 --> 59:10.810
irgendwas anderes und hier die neue Adresse und dann wieder von der

59:10.810 --> 59:13.750
neuen Adresse beginnend nach T-Zugriff, also ungefähr hier hätte ich

59:13.750 --> 59:16.610
dann quasi die neuen Daten abgreifbar.

59:18.030 --> 59:18.910
Für Lesen.

59:19.130 --> 59:22.010
Für Schreiben müsste ich natürlich entsprechend die Daten hier schon

59:22.010 --> 59:23.670
zusammen mit der Adresse anlegen.

59:27.680 --> 59:33.760
Gut, das galt eigentlich das gerade gesehene für quasi alle Formen von

59:33.760 --> 59:34.300
Speichern.

59:34.800 --> 59:37.560
Und dann gibt es halt ein paar Sachen, die sind spezifisch für

59:37.560 --> 59:38.820
verschiedene Arten von Speichern.

59:40.400 --> 59:42.980
Deswegen gucken wir erstmal, was gibt es denn für Arten von Speichern.

59:43.420 --> 59:46.740
Und wir gucken uns hier eigentlich nur an Speicher, die irgendwie mit

59:46.740 --> 59:51.060
Halbleiter -Technologie, also mit, ja, das dauert noch ein bisschen,

59:52.880 --> 59:54.860
mit Transistoren halt eben hergestellt wurden.

59:54.860 --> 59:58.260
Man kann natürlich auch Speicher machen, indem man Relais benutzt,

59:58.380 --> 01:00:01.360
oder Speicher machen, indem man gerollte, na egal.

01:00:01.880 --> 01:00:05.440
Also die aktuellen Speicher sind quasi alle Semikondakte, also

01:00:05.440 --> 01:00:06.000
Halbleiter.

01:00:06.420 --> 01:00:08.340
Und dann gibt es auch wieder ein paar neuere Speicher, die sind auch

01:00:08.340 --> 01:00:10.900
seltsam, aber jetzt endlich auch alles Halbleiter-Herstellung, also

01:00:10.900 --> 01:00:12.740
Herstellungstechnologien.

01:00:13.060 --> 01:00:17.700
Und da wird hier einmal unterschieden in Festwertspeicher und Schreib

01:00:17.700 --> 01:00:18.420
-Lesespeicher.

01:00:18.840 --> 01:00:23.740
Also Festwertspeicher einfach im Sinne von, den Wert kann man nicht

01:00:23.740 --> 01:00:24.100
ändern.

01:00:24.100 --> 01:00:25.980
Den kann man quasi nur lesen.

01:00:26.720 --> 01:00:28.200
Und dann wieder, ja, aber.

01:00:28.540 --> 01:00:30.960
Aber prinzipiell, da stehen quasi Konstanten drin.

01:00:31.040 --> 01:00:32.640
Das ist die Idee vom Festwertspeicher.

01:00:33.920 --> 01:00:37.060
Dann gibt es die Varianten davon, gehen wir mal glatt hier runter, der

01:00:37.060 --> 01:00:41.480
ist wirklich nur lesbar, also der wird quasi bei der Herstellung des

01:00:41.480 --> 01:00:45.140
Chips, wird der Speicher gleich so gebaut, dass der wirklich nur

01:00:45.140 --> 01:00:45.960
gelesen werden kann.

01:00:46.060 --> 01:00:48.020
Den kann man nicht überschreiben, man kann es gar nicht versuchen,

01:00:48.180 --> 01:00:48.940
aber es wird nicht funktionieren.

01:00:50.000 --> 01:01:02.040
Dann gibt es Varianten, die kann man einmal schreiben und das ist

01:01:02.040 --> 01:01:03.200
zerstörend.

01:01:03.400 --> 01:01:06.280
Also das kann man einmal kaputt machen, aber danach kann man es nicht

01:01:06.280 --> 01:01:07.220
wieder reparieren.

01:01:09.280 --> 01:01:09.980
Versuch es mal.

01:01:10.300 --> 01:01:13.340
Also wenn wir uns einen Speicher vorstellen, wie wir es gerade gesehen

01:01:13.340 --> 01:01:13.720
haben.

01:01:14.140 --> 01:01:18.800
Wir haben quasi Zeilen und wir haben Spalten.

01:01:21.300 --> 01:01:25.300
Dann wird eine Zeile aktiviert, soll heißen, auf irgendeiner, auf

01:01:25.300 --> 01:01:29.040
einer einzelnen Zeile kommt irgendwie eine Logisch 1 an.

01:01:29.800 --> 01:01:33.300
Und jetzt ist die Frage, wie kriege ich eigentlich diese Logisch 1 von

01:01:33.300 --> 01:01:36.000
der Zeile auf die Spalte ausgegeben.

01:01:36.420 --> 01:01:40.340
Es ist klar, die müssen jetzt irgendwie verbunden werden können.

01:01:41.060 --> 01:01:41.840
Wie mache ich das?

01:01:41.920 --> 01:01:43.260
Wie schaffe ich die jetzt zu verbinden?

01:01:43.840 --> 01:01:46.940
Wenn ich die dauerhaft mit einem Draht verbinde, dann würde ich quasi

01:01:46.940 --> 01:01:50.520
dauerhaft, also wenn ich jetzt hier ein Draht zwischen machen würde,

01:01:50.580 --> 01:01:53.200
um die zu verbinden, dann würde ich ja quasi immer, wenn hier eine 1

01:01:53.200 --> 01:01:55.260
ausgegeben wird, würde auch eine 1 unten rauskommen.

01:01:55.680 --> 01:01:57.720
Dann habe ich jetzt irgendwie keinen schreibbaren Speicher.

01:01:57.820 --> 01:01:59.160
Dann würde ja immer eine 1 unten rauskommen.

01:01:59.580 --> 01:02:03.180
Also muss ich irgendwas machen, dass die jetzt auf eine Art verbunden

01:02:03.180 --> 01:02:06.220
werden, die halt eben ausdrückt, wird es benutzt oder nicht.

01:02:07.700 --> 01:02:08.440
Wie mache ich das?

01:02:08.780 --> 01:02:10.300
Ich mache dazwischen einen Transistor.

01:02:10.300 --> 01:02:19.580
Und zwar mache ich hier einen Transistor hin, der quasi die beiden

01:02:19.580 --> 01:02:24.660
Leitungen verbindet, je nachdem, was an dem Gate anliegt.

01:02:25.420 --> 01:02:28.340
Und an dem Gate habe ich dann quasi die eigentliche Speicherzelle.

01:02:28.860 --> 01:02:33.240
Wenn die, das wäre jetzt ein Transistor, der bei 1 schaltet, wenn hier

01:02:33.240 --> 01:02:35.720
eine 1 gespeichert wird, also ich muss immer noch irgendwie eine Art

01:02:35.720 --> 01:02:38.740
von Flipflop, es ist kein Flipflop, aber zur Vorstellung, irgendeine

01:02:38.740 --> 01:02:41.780
Art von Flipflop haben, die sich hier einen logischen Wert merkt.

01:02:42.300 --> 01:02:45.680
Und wenn hier quasi eine 1 gespeichert wurde, dem Flipflop, dann wäre

01:02:45.680 --> 01:02:46.740
der Transistor hier lightend.

01:02:47.160 --> 01:02:52.020
Dann würde quasi, wenn die Zeile ausgewählt ist, würde die 1 nach

01:02:52.020 --> 01:02:53.260
unten ausgegeben werden.

01:02:54.340 --> 01:02:56.680
Was passiert jetzt, wenn ich hier eine 0 gespeichert habe?

01:02:57.140 --> 01:02:59.220
Dann sind die beiden Dinger hier nicht verbunden.

01:02:59.700 --> 01:03:04.520
Dann habe ich diese Zeile hier, sorry, die Spalte hier auf Floating

01:03:04.520 --> 01:03:05.240
nicht verbunden.

01:03:05.460 --> 01:03:06.720
Das darf ich natürlich nicht haben.

01:03:06.720 --> 01:03:09.220
Ich muss also quasi irgendwie dafür sorgen, dass da auch was

01:03:09.220 --> 01:03:13.840
ausgegeben wird, wenn hier eine 0, also machen wir hier mal eine 0

01:03:13.840 --> 01:03:16.820
hin, also für den Fall, dass 0, sind die beiden nicht verbunden, dann

01:03:16.820 --> 01:03:19.120
muss hier irgendwie immer noch ein logischer Wert unten rauskommen.

01:03:20.120 --> 01:03:21.480
Was will ich denn haben für einen logischen Wert?

01:03:21.520 --> 01:03:22.320
Ich will eine 0 haben.

01:03:22.740 --> 01:03:27.180
Also mache ich zum Beispiel hier, ein bisschen zu hoch gemalt, egal,

01:03:27.620 --> 01:03:29.600
vielleicht gibt ja der Radierer, nein.

01:03:30.260 --> 01:03:33.780
Ich mache hier, vergesst das daneben, ich mache hier einen Pulldown

01:03:33.780 --> 01:03:35.480
-Widerstand, auch wenn ich ihn jetzt nach oben male.

01:03:36.260 --> 01:03:40.940
Also über einen Widerstand ist die Leitung quasi dauerhaft auf Ground,

01:03:41.000 --> 01:03:41.700
auf 0 gezogen.

01:03:42.400 --> 01:03:45.960
Sprich, wenn hier nichts verbunden ist, dann wird hier unten auch eine

01:03:45.960 --> 01:03:49.580
0 ausgegeben, aber eine schwache 0 über einen Widerstand.

01:03:50.100 --> 01:03:52.960
Wenn die verbunden sind, wenn hier zum Beispiel eine 1 gespeichert

01:03:52.960 --> 01:03:55.180
ist, dann sind die beiden Leitungen verbunden.

01:03:55.780 --> 01:03:59.680
Der hier schreibt eine 0 auf die Leitung, aber über einen Widerstand.

01:03:59.680 --> 01:04:02.720
Der hier schreibt eine 1 ohne Widerstand.

01:04:03.140 --> 01:04:06.320
Ohne im Sinne von ganz, ganz, ganz kleiner Widerstand, weil der

01:04:06.320 --> 01:04:07.800
Transistor halt eben ziemlich gut leitend ist.

01:04:08.140 --> 01:04:11.700
Und somit würde die starke 1, die hier geschrieben wird, diese

01:04:11.700 --> 01:04:15.880
schwache 0 überschreiben und ich könnte unten die 1 lesen.

01:04:16.440 --> 01:04:19.400
So funktionieren das Zusammenschalten von Zeilen und Spalten.

01:04:19.760 --> 01:04:22.320
Und das ist halt eben bei jedem Kreuzungspunkt, muss der Transistor

01:04:22.320 --> 01:04:25.360
sein, der die zusammenschalten kann und noch das eigentliche

01:04:25.360 --> 01:04:27.800
Speicherelement, in dem der Wert halt eben gemerkt werden muss.

01:04:28.660 --> 01:04:34.100
Und bei einem ROM, wenn ich quasi weiß, wenn der Wert hier wirklich

01:04:34.100 --> 01:04:36.820
eine Konstante ist, dann kann ich den Transistor halt gerade

01:04:36.820 --> 01:04:37.240
weglassen.

01:04:37.340 --> 01:04:39.220
Dann mache ich da eine Leitung hin, aber ich mache da keine Leitung

01:04:39.220 --> 01:04:39.460
hin.

01:04:39.580 --> 01:04:41.140
Damit habe ich quasi einen ROM implementiert.

01:04:42.080 --> 01:04:46.320
Für ein PROM, ein einmal programmierbares und danach nur noch lesbares

01:04:46.320 --> 01:04:50.620
Speicherelement, mache ich hier einen Transistor hin, aber der wird so

01:04:50.620 --> 01:04:52.980
dimensioniert, dass ich ihn kaputt machen kann.

01:04:52.980 --> 01:04:59.000
Wenn der Transistor da ist, dann hat er quasi eine Konstante, die er

01:04:59.000 --> 01:04:59.440
verbindet.

01:04:59.580 --> 01:05:03.960
Also hier ist eine Leitung, die verbindet die beiden.

01:05:04.420 --> 01:05:07.840
Aber wenn ich eine gewisse Programmierspannung anlege, also hier nicht

01:05:07.840 --> 01:05:12.460
eine normale 1, keine Ahnung, 1,5 Volt, 3 Volt, sondern eine

01:05:12.460 --> 01:05:15.400
Programmierspannung im Sinne von 10 Volt oder sowas, dann ist die

01:05:15.400 --> 01:05:20.220
Spannung so, dass dann die Leitung hier kaputt gemacht wird.

01:05:20.480 --> 01:05:22.260
Die schmilzt, also die schmilzt wirklich.

01:05:23.020 --> 01:05:25.520
Absichtlich wird die kaputt gemacht und danach ist sie halt eben immer

01:05:25.520 --> 01:05:25.900
getrennt.

01:05:26.020 --> 01:05:28.780
Da kann ich die Leitung hier, die Zeile aktivieren, wie ich möchte.

01:05:29.120 --> 01:05:31.120
Ich werde hier niemals eine Verbindung herkriegen, weil das Ding ist

01:05:31.120 --> 01:05:33.760
kaputt geschmolzen und ich werde hier immer nur noch ein 0 lesen von

01:05:33.760 --> 01:05:34.620
dem Pulldown.

01:05:35.300 --> 01:05:37.740
Wohingegen, wenn ich beim Programmieren die Zeile, den Transistor hier

01:05:37.740 --> 01:05:41.180
heile lasse, dann kann ich die verbinden, dann kann ich die 1 hier

01:05:41.180 --> 01:05:41.460
lesen.

01:05:41.760 --> 01:05:44.100
Und so gesehen kann ich quasi jedes von diesen Verbindungskreuzen

01:05:44.100 --> 01:05:48.480
gezielt beim Programmieren kaputt machen, aber ich kann es danach

01:05:48.480 --> 01:05:49.220
nicht mehr reparieren.

01:05:49.220 --> 01:05:52.520
Ich kann es aber durchaus nachträglich nochmal zusätzliche

01:05:52.520 --> 01:05:54.840
Transistoren kaputt machen, zusätzliche Leitungen kaputt machen.

01:05:55.220 --> 01:05:57.420
Also ich kann immer mehr kaputt machen, wenn ich will, aber ich kann

01:05:57.420 --> 01:05:58.220
es halt nicht mehr reparieren.

01:05:58.720 --> 01:06:01.720
So würde halt eben PROM durchaus mehrmals programmierbar sein, aber

01:06:01.720 --> 01:06:04.140
irgendwas einmal geschmolzenes lässt sich halt nicht mehr heile

01:06:04.140 --> 01:06:04.360
machen.

01:06:04.900 --> 01:06:06.020
So würde ein PROM funktionieren.

01:06:07.200 --> 01:06:12.120
Dann habe ich die Festfeldspeicher, wo das Schreiben rückgängig

01:06:12.120 --> 01:06:13.520
machbar, also löschbar ist.

01:06:14.660 --> 01:06:16.780
Es gibt verschiedene Versionen.

01:06:16.960 --> 01:06:24.040
EPROM war ein Speicher, wo es einen Transistor gab mit einem Floating

01:06:24.040 --> 01:06:24.380
Gate.

01:06:24.660 --> 01:06:27.460
Im Sinne von, das war kein normaler Transistor.

01:06:27.960 --> 01:06:29.160
Na, versuchen wir es mal.

01:06:30.020 --> 01:06:32.960
Ein normaler Transistor habt ihr ja irgendwo mal gesehen.

01:06:33.620 --> 01:06:36.560
Der würde so aussehen, ich habe hier irgendwie einen Kanal, ich hätte

01:06:36.560 --> 01:06:39.080
hier einen Source und einen Drain.

01:06:39.240 --> 01:06:42.100
Hier ist irgendwie ein Stück Isolation, da drüber ist das Gate.

01:06:42.100 --> 01:06:52.200
Jetzt habe ich bei einem Floating Gate Transistor noch eine Linie hier

01:06:52.200 --> 01:06:57.460
zwischen dem normalen Gate und dem Kanal.

01:06:57.480 --> 01:07:00.680
Es sollte noch eine weitere Metallebene sein, die ist aber nirgendwo

01:07:00.680 --> 01:07:01.280
angeschlossen.

01:07:01.800 --> 01:07:04.160
Also die ist mit nichts verbunden.

01:07:05.860 --> 01:07:09.320
Aber der normale Feldeffekt Transistor funktioniert ja so, dass ich

01:07:09.320 --> 01:07:13.120
durch magnetische Felder Ladung anziehen kann und damit diesen Kanal

01:07:13.120 --> 01:07:13.600
aufbauen.

01:07:13.680 --> 01:07:14.740
Das sehen wir gleich noch in einer anderen Folie.

01:07:15.480 --> 01:07:18.020
Und hier ist es so, bei diesem Floating Gate, ich kann auch wieder

01:07:18.020 --> 01:07:21.180
durch eine etwas höhere Programmierspannung, kann ich die Ladung dazu

01:07:21.180 --> 01:07:23.440
motivieren, obwohl da keine metallische Verbindung ist.

01:07:23.560 --> 01:07:26.720
Obwohl dieses Floating Gate einfach nur schwebt.

01:07:28.040 --> 01:07:32.560
Kann ich Ladung motivieren, aus dem Kanal raus in dieses Floating Gate

01:07:32.560 --> 01:07:35.660
reinzugehen und dann bleibt die Ladung auf dem Floating Gate drauf.

01:07:35.780 --> 01:07:36.580
Die liegt da einfach.

01:07:37.000 --> 01:07:40.760
Und dann kann ich an dem normalen Gate anlegen, was für eine Spannung

01:07:40.760 --> 01:07:41.140
ich will.

01:07:41.540 --> 01:07:44.480
Das Feld vom normalen Gate kommt gar nicht mehr an den Kanal dran.

01:07:45.000 --> 01:07:48.320
Wenn ich versuchen würde, diesen Teil nochmal raus zu zoomen, hätten

01:07:48.320 --> 01:07:53.120
wir quasi das normale Gate, dann irgendwo dazwischen das Floating Gate

01:07:53.120 --> 01:07:55.020
und irgendwo unten drunter den Kanal.

01:07:55.020 --> 01:07:59.420
Und normalerweise würde das Gate ja eine Auswirkung auf den Kanal

01:07:59.420 --> 01:07:59.800
haben.

01:08:00.280 --> 01:08:02.600
Aber dadurch, dass jetzt ein Floating Gate dazwischen ist, auf dem

01:08:02.600 --> 01:08:05.840
Ladung drauf ist, wird das magnetische Feld, was von dem Gate

01:08:05.840 --> 01:08:07.960
ausgestrahlt wird, kommt nur bis hier.

01:08:08.260 --> 01:08:09.440
Kommt gar nicht bis zum Kanal.

01:08:09.900 --> 01:08:12.480
Und was auch immer hier für eine Ladung drauf ist, die bestimmt, ob

01:08:12.480 --> 01:08:14.380
der Kanal hier Leitend ist oder Sperrend.

01:08:15.600 --> 01:08:18.760
Und dann kann ich mit höheren Programmierspannungen Elektronen dazu

01:08:18.760 --> 01:08:22.620
bringen, in dieses Floating Gate reinzuhüpfen oder aus dem Floating

01:08:22.620 --> 01:08:23.600
Gate wieder rauszufließen.

01:08:23.600 --> 01:08:27.600
Und bei dem EEPROM war es so, dass man zum Schreiben, zum

01:08:27.600 --> 01:08:30.540
Programmieren halt eine höhere Programmierspannung benutzt hat und

01:08:30.540 --> 01:08:31.520
dann konnte man sie wieder löschen.

01:08:31.680 --> 01:08:34.740
Das Löschen war damals mit Licht, mit UV-Licht.

01:08:35.200 --> 01:08:40.440
Das waren Chips, die hatten wirklich ein Glas... da war ein Glasdeckel

01:08:40.440 --> 01:08:41.460
auf dem Chip oben drauf.

01:08:41.760 --> 01:08:43.900
Dann konnte man die einfach in die Sonne legen oder es gab spezielle

01:08:43.900 --> 01:08:47.760
Löschgeräte, letztendlich eine UV-Lampe, mit denen man quasi die

01:08:47.760 --> 01:08:48.200
löschen konnte.

01:08:48.200 --> 01:08:52.260
Und die Energie von der UV-Strahlung hat halt eben die Elektronen aus

01:08:52.260 --> 01:08:53.480
dem Floating Gate wieder rausgeholt.

01:08:56.700 --> 01:09:00.060
Beim EEPROM, das E steht hier für löschbar, erasable.

01:09:01.160 --> 01:09:03.580
Das hier ist dann electrically erasable.

01:09:03.780 --> 01:09:06.400
Ich brauche kein Licht mehr zum Löschen, sondern ich kann mit Strom

01:09:06.400 --> 01:09:07.280
löschen, mit Leistung.

01:09:07.920 --> 01:09:09.940
Letztendlich genau das gleiche, ich habe immer noch ein Floating Gate

01:09:09.940 --> 01:09:13.360
und mit anderen Materialien und anderen Anschlüssen kann ich halt eben

01:09:13.360 --> 01:09:15.520
jetzt auch elektrisch die Ladung aus dem Floating Gate wieder

01:09:15.520 --> 01:09:15.960
rausholen.

01:09:18.340 --> 01:09:22.200
Flash -Speicher, wie ihn jeder vom USB-Stick kennt, ist eine Variante

01:09:22.200 --> 01:09:26.480
von EEPROM, wo man zum Schreiben und zum Löschen nicht wie beim

01:09:26.480 --> 01:09:29.580
normalen EEPROM eine höhere Spannung braucht, sondern wo die ganz

01:09:29.580 --> 01:09:32.300
normale Arbeitsspannung auch ausreicht zum Schreiben und zum Löschen,

01:09:32.380 --> 01:09:34.360
aber ansonsten ist es wie im EEPROM.

01:09:34.980 --> 01:09:38.100
Dann gibt es die andere Hälfte, Schreib-Lese-Speicher, die man quasi

01:09:38.100 --> 01:09:41.220
wahlfrei schreiben, lesen, löschen, wie man möchte kann.

01:09:41.220 --> 01:09:44.700
Es gibt einmal SRAM, statisches RAM, das gucken wir uns gleich an, und

01:09:44.700 --> 01:09:46.460
dann gibt es noch DRAM, das gucken wir uns danach an.

01:09:48.340 --> 01:09:52.820
Was es auch gibt, sind Mischungen aus den beiden, quasi-statisches

01:09:52.820 --> 01:09:57.300
RAM, auch Pseudo-SRAM genannt, ist einfach, dass es in Wirklichkeit

01:09:57.300 --> 01:09:58.500
ein DRAM-Speicher ist.

01:09:58.920 --> 01:10:03.320
DRAM hat eine hohe Kapazität, im Sinne von da passt viel Bit pro

01:10:03.320 --> 01:10:07.520
Fläche, aber ist schwierig anzusteuern.

01:10:07.520 --> 01:10:09.380
Wir sehen noch nachher, wie DRAM funktioniert.

01:10:09.780 --> 01:10:13.940
Bei diesem Pseudo-SRAM ist quasi ein Controller mit dabei, der nach

01:10:13.940 --> 01:10:16.340
außen so tut, als wäre das ein SRAM.

01:10:16.440 --> 01:10:19.780
Ich kann das Ding so einfach benutzen wie ein SRAM und die ganze

01:10:19.780 --> 01:10:23.000
Ansteuerung von dem DRAM ist innen drin, die ist vor mir versteckt.

01:10:23.460 --> 01:10:25.100
Das heißt, ich muss mich nicht drum kümmern, ich muss mich nicht um

01:10:25.100 --> 01:10:26.180
Timings kümmern und sowas.

01:10:26.560 --> 01:10:30.100
Also die Benutzung wie SRAM, aber halt nicht so schnell wie SRAM.

01:10:30.240 --> 01:10:33.420
Aber dafür die höhere Kapazität, mehr Megabit, so wie DRAM.

01:10:35.080 --> 01:10:37.000
Genauso gibt es auch hier, das ist jetzt nicht wirklich eine

01:10:37.000 --> 01:10:40.280
technologische Kombination, ich habe einen DRAM mit einem SRAM

01:10:40.280 --> 01:10:40.740
Interface.

01:10:41.680 --> 01:10:46.540
Das hier ist was anderes, das ist einfach, diese EEPROMs hatten immer

01:10:46.540 --> 01:10:50.660
noch, also die normalen EEPROMs, eine sehr langsame Schreib- und

01:10:50.660 --> 01:10:53.220
Löschzeit und das wird inzwischen immer besser.

01:10:53.580 --> 01:10:55.500
Nicht nur bei Flash, sondern auch bei anderen Technologien, wie man

01:10:55.500 --> 01:10:56.100
das machen kann.

01:10:56.640 --> 01:10:59.700
Die werden inzwischen teilweise so schnell, vom Schreiben und vom

01:10:59.700 --> 01:11:02.520
Löschen, dass sie der DRAM, dem DRAM Speicher Konkurrenz machen.

01:11:02.920 --> 01:11:05.000
Und dann kann man sich überlegen, dann könnte man doch auch irgendwas

01:11:05.000 --> 01:11:07.600
anbieten, was ich quasi als Hauptspeicher benutze.

01:11:08.200 --> 01:11:11.680
Eigentlich ist ja die Idee von diesen Festwertspeichern, wenn ich die

01:11:11.680 --> 01:11:14.840
Versorgungsspannung abziehe, dann behalten sie ihren Wert.

01:11:15.480 --> 01:11:18.600
Also der gespeicherte Wert bleibt erhalten, wenn ich einen USB-Stick

01:11:18.600 --> 01:11:21.200
rausziehe, der wird ja nicht gelöscht dabei, der merkt sich ja das.

01:11:22.180 --> 01:11:25.320
Wohingegen SRAM und DRAM, wenn ich den Stromversorgung abschalte, dann

01:11:25.320 --> 01:11:26.400
ist der Inhalt verloren gegangen.

01:11:27.100 --> 01:11:31.480
Also hier ist gemeint, der Wert bleibt behalten, non-volatile, nicht

01:11:31.480 --> 01:11:35.520
flüchtig, aber ich kann es quasi benutzen für meinen normalen

01:11:35.520 --> 01:11:36.080
Hauptspeicher.

01:11:36.220 --> 01:11:39.960
Nicht nur als langsamen, trägen, großen Massenspeicher, sondern quasi

01:11:39.960 --> 01:11:43.060
als Hauptspeicher, weil es inzwischen einfach relativ schnell geworden

01:11:43.060 --> 01:11:43.320
ist.

01:11:44.680 --> 01:11:47.780
Auch diese Nicht-Flüchtigkeit ist quasi einstellbar.

01:11:48.480 --> 01:11:52.200
Je nachdem, mit wie viel Schreibspannung und vor allem der Schreibzeit

01:11:52.200 --> 01:11:56.220
ich arbeite, ergibt sich daraus, wie lange die Werte erhalten bleiben.

01:11:56.620 --> 01:11:59.420
Also ich kann sozusagen was machen, wie wenn ich bei einem EEPROM oder

01:11:59.420 --> 01:12:03.240
einem Flash EEPROM weniger, also kürzer, zeitlich gesehen kürzer

01:12:03.240 --> 01:12:06.660
schreibe, dann werden die Daten trotzdem noch gemerkt, wenn ich den

01:12:06.660 --> 01:12:08.740
Strom rausziehe, aber vielleicht nur ein Jahr.

01:12:08.740 --> 01:12:11.760
Wohingegen, wenn ich ordentlich Zeit und Energie ins Schreiben

01:12:11.760 --> 01:12:14.940
investiere, dann sind die auch noch 10 oder 100 Jahre auf dem USB

01:12:14.940 --> 01:12:15.480
-Stick drauf.

01:12:15.940 --> 01:12:18.660
Also man kann quasi hier Trade-Offs machen, weil, ja, reicht ja

01:12:18.660 --> 01:12:19.260
normalerweise.

01:12:19.600 --> 01:12:21.880
Wird ja auch in einer Sekunde wahrscheinlich reichen für die meisten

01:12:21.880 --> 01:12:22.580
Hauptspeichersachen.

01:12:23.240 --> 01:12:25.140
Also da kann man Kombinationen daraus herstellen.

01:12:27.740 --> 01:12:30.100
Gut, wie sehen diese Transistoren eigentlich aus?

01:12:30.180 --> 01:12:33.280
Das habe ich gerade schon quasi versucht hinzumalen, aber hier ist

01:12:33.280 --> 01:12:33.880
nochmal ein ordentlich.

01:12:36.000 --> 01:12:37.640
Habt ihr auch gesehen in TI1.

01:12:38.120 --> 01:12:42.680
Also wir haben halt eben ein Substrat, in dem Fall ist es ein NMOS

01:12:42.680 --> 01:12:44.840
-Transistor, also haben wir ein P-dotiertes Substrat.

01:12:46.180 --> 01:12:51.160
Und da haben wir zwei dotierte Regionen drin für Source und für Drain.

01:12:52.640 --> 01:12:57.200
Obendrauf haben wir eine unrealistisch dicke Isolationsschicht, die

01:12:57.200 --> 01:12:59.920
ist dünn, die ist richtig dünn in Wirklichkeit.

01:12:59.920 --> 01:13:03.980
Und wieder obendrauf haben wir den Gate-Anschluss.

01:13:04.400 --> 01:13:08.060
So, beim NMOS-Transistor ist quasi der Source immer an den Ground

01:13:08.060 --> 01:13:09.700
angeschlossen, so funktionieren die Dinge am besten.

01:13:10.440 --> 01:13:16.000
Und normalerweise hätte ich jetzt hier diese P-Dotierung, hier überall

01:13:16.000 --> 01:13:18.280
sind so P-Teilchen verteilt in diesem Substrat.

01:13:18.920 --> 01:13:22.240
Und dadurch, dass quasi hier wollen Elektronen ankommen, würden gerne

01:13:22.240 --> 01:13:25.460
weiterkommen, aber nicht weiter, weil hier überall diese Plus-Teilchen

01:13:25.460 --> 01:13:26.500
in der Gegend rumwurschteln.

01:13:26.500 --> 01:13:30.440
Und somit wäre keine Verbindung, wohingegen, wie hier hingemalt, wenn

01:13:30.440 --> 01:13:35.400
ich am Gate logisch eins anlege, also quasi ganz viele, naja, das

01:13:35.400 --> 01:13:36.460
Gegenteil von Elektronen, was auch immer.

01:13:36.580 --> 01:13:40.740
Also die Abwesenheit von Elektronen hier anliegen habe, dann wird

01:13:40.740 --> 01:13:45.320
quasi, ja, durch ein magnetisches Feld werden Elektronen, die hier

01:13:45.320 --> 01:13:48.080
irgendwo verfügbar sind, und zwar kommen die von hier, werden hier

01:13:48.080 --> 01:13:51.960
rausgesogen, sammeln sich hier an und bilden damit einen Kanal, sodass

01:13:51.960 --> 01:13:54.580
hier Elektronen wirklich rausfließen können ins Drain.

01:13:54.580 --> 01:13:58.280
Wohingegen umgekehrt, wenn ich hier 0 angelegt hätte, würden alle

01:13:58.280 --> 01:14:01.500
Elektronen, die hier sind, weggedrückt, nach da oder nach da, und die

01:14:01.500 --> 01:14:04.600
Plus -Teilchen würden angezogen, würden hier dran kleben, und damit

01:14:04.600 --> 01:14:07.020
ist es nicht möglich, einen Kanal zu bilden, dadurch sperrt der.

01:14:07.060 --> 01:14:10.680
Und so kann man den halt eben wechselnd zwischen leitend und sperrend

01:14:10.680 --> 01:14:11.540
hin - und herschalten.

01:14:16.560 --> 01:14:19.420
Kondensatoreffekt, das ist ein Feld-Effekt, ein magnetischer Effekt,

01:14:19.780 --> 01:14:24.600
quasi wenn ich hier Plus hinmache, wird hier Minus angezogen und

01:14:24.600 --> 01:14:25.880
umgekehrt halt eben.

01:14:25.940 --> 01:14:30.140
Das kann ich benutzen, um halt eben die Leitfähigkeit zu steuern.

01:14:33.800 --> 01:14:37.900
Ja, ist im Wesentlichen dasselbe nochmal.

01:14:39.720 --> 01:14:43.840
Endkanal leitet, wenn ich...

01:14:43.840 --> 01:14:48.020
Ja genau, bei 0 sperrt er, und wir hatten gerade das Beispiel, wenn

01:14:48.020 --> 01:14:50.200
ich eine 1 anlege, dann leitet er.

01:14:50.640 --> 01:14:51.020
Passt.

01:14:53.480 --> 01:14:56.120
Gut, einfach nochmal zusammenfassend, wie die Transistoren

01:14:56.120 --> 01:14:57.880
funktionieren, aber wie gesagt, das hattet ihr ja eigentlich schon in

01:14:57.880 --> 01:14:58.360
TI1.

01:14:59.180 --> 01:15:03.480
Ich habe NMOS-Transistoren in rot, der linke hier, und ich habe PMOS

01:15:03.480 --> 01:15:05.260
-Transistoren in grün, der rechte hier.

01:15:06.920 --> 01:15:12.960
Der NMOS-Transistor leitet, schaltet durch, wenn ich eine logisch 1 am

01:15:12.960 --> 01:15:17.080
Gate anliegen habe, und der PMOS gerade umgekehrt, wenn ich eine 0 am

01:15:17.080 --> 01:15:18.020
Gate anliegen habe.

01:15:18.020 --> 01:15:23.100
Man malt es dann auch meistens so, weil der NMOS-Transistor halt sehr

01:15:23.100 --> 01:15:25.340
gut darin ist, Elektronen durchzuschalten.

01:15:25.940 --> 01:15:28.700
Wird da unten normalerweise an Ground angeschlossen, deswegen wird

01:15:28.700 --> 01:15:30.280
auch meist der Source unten hingemalt.

01:15:30.700 --> 01:15:32.740
Ansonsten muss man halt eben diese Pfeilrichtung gucken.

01:15:32.820 --> 01:15:35.380
Aber da gibt es auch zig verschiedene Arten, sagen wir mal Standards,

01:15:35.560 --> 01:15:36.880
wie man die Symbole hinmalen kann.

01:15:37.240 --> 01:15:38.440
Das wäre halt eben eine davon.

01:15:40.880 --> 01:15:42.420
Andere... ach ist egal, erstmal die Version hier.

01:15:42.860 --> 01:15:44.420
Und der PMOS halt gerade das Gegenteil.

01:15:44.420 --> 01:15:49.680
Wenn ich eine 0 am Gate anliegen habe, dann wäre der hier sperrend,

01:15:50.060 --> 01:15:53.500
der wäre leitend, also der würde von oben die normalerweise

01:15:53.500 --> 01:15:56.000
Versorgungsspannung nach unten durchgeben.

01:15:56.900 --> 01:16:00.320
Bei einer 1 ist es gerade umgekehrt, bei einer 1 würde der von Source

01:16:00.320 --> 01:16:03.960
nach Drain durchschalten, und der hier wäre sperrend, der wäre

01:16:03.960 --> 01:16:04.400
getrennt.

01:16:07.160 --> 01:16:09.920
So, und jetzt gibt es halt eben noch die verschiedenen

01:16:09.920 --> 01:16:12.340
Speicherelemente.

01:16:12.340 --> 01:16:16.600
Er hat ja vorhin schon gezeigt, angedeutet, gekritzelt, wie man diese

01:16:16.600 --> 01:16:18.500
Zeilen und Spalten zusammenschaltet.

01:16:18.860 --> 01:16:21.340
Und gesagt, ja jetzt müsste da doch irgendwie so ein Speicherelement

01:16:21.340 --> 01:16:25.000
sein, ein Flipflop zum Beispiel, der dann eigentlich den Wert merkt,

01:16:25.040 --> 01:16:27.240
und jetzt ist es halt eben kein Flipflop, sondern es ist eine SRAM

01:16:27.240 --> 01:16:27.480
-Zelle.

01:16:27.940 --> 01:16:30.540
Und die SRAM-Zelle sieht aus wie hier gemalt.

01:16:31.760 --> 01:16:37.460
Da habe ich auch wieder die Zeilen, und ich habe sogar zwei Spalten,

01:16:38.420 --> 01:16:41.060
aber die greifen beide auf die gleiche SRAM-Zelle zu.

01:16:41.060 --> 01:16:46.460
Dann habe ich hier Transistoren, mit denen ich halt eben die Zeile und

01:16:46.460 --> 01:16:50.080
die Spalte verbinden kann, also quasi sollte überhaupt schreiben oder

01:16:50.080 --> 01:16:51.920
lesen darauf zugreifen, hier genau das andere.

01:16:52.440 --> 01:16:55.180
Und jetzt habe ich hier das eigentliche Speicherelement.

01:16:55.980 --> 01:17:00.000
Das eigentliche Speicherelement ist eigentlich relativ einfach

01:17:00.000 --> 01:17:00.310
aufgebaut.

01:17:02.150 --> 01:17:05.010
Also es sieht jetzt verwirrend aus, wenn man es noch nie gesehen hat.

01:17:05.430 --> 01:17:09.050
Aber wenn man es sich mal ein bisschen anguckt, dann habe ich quasi

01:17:09.050 --> 01:17:14.870
hier zwei Transistoren, die beiden, bei denen die Gates gerade

01:17:14.870 --> 01:17:16.090
zusammengeschaltet sind.

01:17:16.190 --> 01:17:19.670
Also hier gibt es ein Gate, was an beiden Transistoren geht, und die

01:17:19.670 --> 01:17:22.510
Ausgänge der beiden sind auch wieder zusammengeschaltet.

01:17:22.950 --> 01:17:23.650
Was ist das?

01:17:23.890 --> 01:17:24.810
Das ist ein Inverter.

01:17:26.610 --> 01:17:27.430
Und was habe ich hier?

01:17:27.750 --> 01:17:28.510
Dasselbe nochmal.

01:17:28.510 --> 01:17:32.670
Ich habe hier zwei Transistoren, wo die Gates zusammengeschaltet sind

01:17:32.670 --> 01:17:36.050
und wo die Ausgänge der beiden auch wieder zusammengeschaltet sind.

01:17:36.170 --> 01:17:37.930
Also ich habe hier einfach nur zwei Inverter.

01:17:38.550 --> 01:17:41.270
Wenn ich es hinmalen würde, würde es so aussehen.

01:17:41.410 --> 01:17:42.950
Ich glaube, Inverter hatten wir ja so gemalt.

01:17:43.490 --> 01:17:47.610
Und davon der Ausgang, das Gate, mal sehen, wenn das hier der rechte

01:17:47.610 --> 01:17:53.050
der beiden ist, der Ausgang wäre der hier, der geht jetzt gerade ans

01:17:53.050 --> 01:17:54.030
Gate von dem anderen.

01:17:54.030 --> 01:17:57.430
Das heißt, wenn ich jetzt hier den Inverter von rechts nach links

01:17:57.430 --> 01:17:59.690
malen würde, dann wäre das so.

01:18:00.330 --> 01:18:01.270
Das ist hier verbunden.

01:18:02.610 --> 01:18:05.810
So, jetzt sind wir bei dem linken, beim Gate von dem linken angekommen

01:18:05.810 --> 01:18:08.990
und der Ausgang von den beiden, das ist der hier, der Ausgang von dem

01:18:08.990 --> 01:18:11.670
Inverter, geht gerade an das Gate von dem ersten.

01:18:12.470 --> 01:18:15.110
Also so eine lustige kleine Rückkopplung.

01:18:16.010 --> 01:18:18.470
Man kann sehen, das ist an sich erstmal stabil.

01:18:18.970 --> 01:18:23.410
Im Sinne von, angenommen, hier würde eine Logisch 1 anliegen, dann

01:18:23.410 --> 01:18:26.510
wird das hier invertiert auf eine Logisch 0, wird das hier invertiert

01:18:26.510 --> 01:18:27.330
auf eine Logisch 1.

01:18:27.790 --> 01:18:30.250
Das merkt sich quasi diesen Zustand.

01:18:30.450 --> 01:18:34.050
Das wäre dann stabil, würde immer diesen Wert enthalten.

01:18:34.050 --> 01:18:40.050
Und wenn ich jetzt aber noch in der Lage wäre, hier von außen mit

01:18:40.050 --> 01:18:45.250
Gewalt eine 0 reinzudrücken, die ein stärkerer Treiber ist, die also

01:18:45.250 --> 01:18:47.290
diese 1 hier überschreiben kann.

01:18:47.490 --> 01:18:50.310
Wenn die beide gleich stark sind, also wenn der Treiber, der Ausgang

01:18:50.310 --> 01:18:53.810
hier, genauso stark ist wie die 0, die von hier reinkommt, dann würde

01:18:53.810 --> 01:18:55.530
irgendwas schief gehen, also kaputt gehen letztendlich.

01:18:56.130 --> 01:18:59.390
Aber wenn ich hier quasi einen schwachen Treiber habe, der quasi

01:18:59.390 --> 01:19:03.330
dominiert überschrieben werden kann von einem externen, der externe

01:19:03.330 --> 01:19:07.370
wird quasi hier aufgeschaltet, der geht dann hier durch, dann kann ich

01:19:07.370 --> 01:19:10.930
die 1, die hier eigentlich am Ausgang anliegt, überschreiben mit der

01:19:10.930 --> 01:19:11.210
0.

01:19:11.450 --> 01:19:14.450
Dann hätte ich quasi hier die 0, weil sie stärker ist, dann hätte ich

01:19:14.450 --> 01:19:17.570
danach hier die 1, dann habe ich danach hier die 0 und dann ist es

01:19:17.570 --> 01:19:18.070
wieder stabil.

01:19:18.430 --> 01:19:21.630
Also ich kann den quasi von außen mit Gewalt in einen anderen Zustand

01:19:21.630 --> 01:19:22.330
reinzwingen.

01:19:22.330 --> 01:19:25.710
Und wenn ich danach hier wieder abtrenne, also den Transistor wieder

01:19:25.710 --> 01:19:29.110
auf Disconnect, nicht verbunden schalte, dann hat er sich den neuen

01:19:29.110 --> 01:19:29.990
Zustand gemerkt.

01:19:30.150 --> 01:19:33.550
Also ich kann ihn somit von außen hin und her zwingen zwischen den

01:19:33.550 --> 01:19:33.790
beiden.

01:19:34.090 --> 01:19:37.170
Und das Merken ist wirklich einfach zwei Inverter, die im Kreis

01:19:37.170 --> 01:19:37.790
verbunden sind.

01:19:39.470 --> 01:19:41.410
Die Varianten gucken wir uns gleich noch an.

01:19:43.410 --> 01:19:47.790
Gut, also wir haben eine SRAM-Zelle im Allgemeinen, zwei kreuzweise

01:19:47.790 --> 01:19:51.310
rückgekoppelte Inverter, T0, T2, T1, T3.

01:19:51.770 --> 01:19:57.570
Mal schauen, T0, T2, das ist gerade der eine Inverter, T1, T3 ist der

01:19:57.570 --> 01:20:01.290
andere Inverter, T0, T2, T1, T3, das sind die beiden Inverter.

01:20:01.290 --> 01:20:06.370
Und dann noch zwei Transistoren, um halt eben von der einen Seite oder

01:20:06.370 --> 01:20:08.870
der anderen Seite Werte rein zu zwingen bzw.

01:20:08.870 --> 01:20:09.470
zu lesen.

01:20:09.710 --> 01:20:13.330
Das wären quasi dann die Anschlüsse an die Lese- und Schreibleitungen.

01:20:14.550 --> 01:20:17.270
Und da das Ding halt nun mal sechs Transistoren braucht, spricht man

01:20:17.270 --> 01:20:19.430
im Allgemeinen von einer 6T-Transistorzelle.

01:20:19.910 --> 01:20:22.310
Und dann gibt es auch Vorschläge, wie man das mit weniger Transistoren

01:20:22.310 --> 01:20:22.850
machen könnte.

01:20:22.970 --> 01:20:25.390
Dafür wird es für gewöhnlich langsamer oder kann sich nicht mehr so

01:20:25.390 --> 01:20:25.910
gut merken.

01:20:25.910 --> 01:20:28.430
Und dann gibt es wieder andere Vorschläge, die sagen, ja, wir können

01:20:28.430 --> 01:20:31.350
auch noch mehr Transistoren benutzen, dann wird es stabiler, aber auch

01:20:31.350 --> 01:20:31.890
größer.

01:20:32.230 --> 01:20:35.130
Also da gibt es wirklich Forschungsgebiete, die sich darum kümmern,

01:20:35.250 --> 01:20:38.370
wie man SRAM-Zellen noch hier oder da ein bisschen optimieren kann.

01:20:38.730 --> 01:20:41.050
Die optimieren aber für gewöhnlich auf sehr, sehr, sehr viel tieferen

01:20:41.050 --> 01:20:43.970
Ebenen, auf physikalischen Ebenen und nicht auf so Bildchen, wie wir

01:20:43.970 --> 01:20:44.930
es hier gerade gemacht haben.

01:20:46.970 --> 01:20:51.570
Wie bei CMOS immer, nur zum Umschaltzeitpunkt fließt Strom.

01:20:51.570 --> 01:20:57.550
Soll heißen, von den Transistoren hier, der Ausgang, also hier habe

01:20:57.550 --> 01:21:00.390
ich Versorgungsspannung, sagen wir mal, der leitet das durch, dann

01:21:00.390 --> 01:21:03.090
geht die Versorgungsspannung, hier kommt sie nicht weiter, von hier,

01:21:03.350 --> 01:21:07.990
der sperrt, geht sie nach hier und hier ist sie beim Gate, hier auch,

01:21:08.370 --> 01:21:09.230
und da hört sie auf.

01:21:09.570 --> 01:21:11.070
Da ist ja jetzt keine leitende Verbindung.

01:21:11.250 --> 01:21:14.930
Das ist ja quasi, das Gate ist ja nicht elektrisch verbunden mit dem,

01:21:15.010 --> 01:21:16.950
was danach kommt, sondern es ist isoliert, es wird ja nur ein

01:21:16.950 --> 01:21:17.870
Magnetfeld aufgebaut.

01:21:17.870 --> 01:21:23.610
Also, wenn der Zustand einfach nur gehalten wird, fließt erstmal kein

01:21:23.610 --> 01:21:27.090
Strom und nur wenn ich quasi von außen einen neuen Wert rein zwinge,

01:21:27.150 --> 01:21:29.630
beim Umschalten, beim Wechseln, beim Schreiben von der SRAM-Zelle,

01:21:30.210 --> 01:21:32.610
dann fließt halt eben Strom, den ich zum Schreiben einfach brauche.

01:21:34.030 --> 01:21:36.790
Noch eine andere Variante, die man machen kann, wenn man eben nicht

01:21:36.790 --> 01:21:40.610
CMOS will, kann man auch nur NMOS-Transistoren oder auch alternativ

01:21:40.610 --> 01:21:42.670
nur PMOS-Transistoren benutzen.

01:21:42.910 --> 01:21:43.990
Wie würde das aussehen?

01:21:44.470 --> 01:21:47.670
Letztendlich geht es einfach darum, wie man den Inverter bauen würde.

01:21:48.050 --> 01:21:50.410
Und hier ist klar, wenn ich einen Inverter habe, hier habe ich ja

01:21:50.410 --> 01:21:54.270
einen NMOS- und einen PMOS-Transistor, wenn ich jetzt nur einen der

01:21:54.270 --> 01:21:59.810
beiden Transistorarten benutzen darf, sagen wir mal ich darf nur den

01:21:59.810 --> 01:22:02.610
Transistor hier benutzen, den NMOS-Transistor, dann müsste der

01:22:02.610 --> 01:22:05.110
Transistor hier wegfallen, aber dann ist es ja kein Inverter mehr.

01:22:05.110 --> 01:22:06.530
Versuchen wir mal, eine Werte hinzumalen.

01:22:06.970 --> 01:22:08.110
Also ich hätte quasi...

01:22:09.810 --> 01:22:10.910
Mal von links nach rechts.

01:22:11.010 --> 01:22:15.170
Also wir hätten die Eingabe, die geht normalerweise an zwei

01:22:15.170 --> 01:22:17.190
Transistoren, an die Gates dran.

01:22:17.730 --> 01:22:21.010
Der eine holt die Versorgungsspannung und schaltet sie auf die

01:22:21.010 --> 01:22:26.250
Ausgabe, der andere holt sich Ground und schaltet sie auf die Ausgabe.

01:22:26.750 --> 01:22:31.770
Und wenn ich jetzt den einen der beiden Transistoren weglassen soll, z

01:22:31.770 --> 01:22:32.050
.B.

01:22:32.210 --> 01:22:34.810
den hier, dann kann ich ja den nicht weglassen, sondern dann hätte ich

01:22:34.810 --> 01:22:37.730
ja, wenn ich den weglassen würde, dann wäre der Ausgang ja hier

01:22:37.730 --> 01:22:42.930
entweder 0, also das Ground durchschaltet, wenn der Input eine 1 war.

01:22:46.370 --> 01:22:52.650
Oder, wenn der Input eine 0 war, würde der hier sperren und hier, der

01:22:52.650 --> 01:22:57.330
ist ja weg, dann wäre der Ausgang, ja nix, floating, undefiniert.

01:22:57.750 --> 01:22:59.150
Und mit undefiniert werde ich nicht glücklich.

01:22:59.150 --> 01:23:02.570
Und deswegen mache ich, wenn ich den hier oben weglassen muss, dann

01:23:02.570 --> 01:23:05.530
lasse ich ihn nicht ganz weg, sondern ich ersetze ihn durch so ein

01:23:05.530 --> 01:23:06.070
Konstrukt.

01:23:06.470 --> 01:23:09.370
Und dieses Konstrukt ist jetzt der gleiche Art von Transistor, den ich

01:23:09.370 --> 01:23:11.490
hier unten auch benutzt habe, der gleiche Art von Transistor, den ich

01:23:11.490 --> 01:23:12.990
hier benutzt habe, benutze ich auch hier.

01:23:12.990 --> 01:23:17.750
Aber ich schalte Gate und Source hier zusammen.

01:23:18.530 --> 01:23:20.850
Hier habe ich ja die Versorgungsspannung, also hier oben habe ich ja

01:23:20.850 --> 01:23:21.890
die Versorgungsspannung gehabt.

01:23:23.250 --> 01:23:28.130
Das heißt, der Transistor hier, der wäre bei einer 1 immer lightend.

01:23:28.670 --> 01:23:31.630
Was bringt das jetzt, wenn ich da einen immer lightenden Transistor

01:23:31.630 --> 01:23:31.930
habe?

01:23:32.650 --> 01:23:35.310
Je nachdem, wie ich den Transistor dimensioniere, je nachdem, wie

01:23:35.310 --> 01:23:39.510
stark ich die Regionen dotiere, wie groß ich die verschiedenen

01:23:39.510 --> 01:23:42.990
Regionen mache, kann ich den quasi als Widerstand, ich kann den so

01:23:42.990 --> 01:23:45.930
implementieren, so bauen, dass er quasi wie ein Widerstand

01:23:45.930 --> 01:23:46.490
funktioniert.

01:23:46.490 --> 01:23:51.250
Was ich dann habe, ist hier an der Stelle keinen Anschluss mehr an den

01:23:51.250 --> 01:23:55.010
Eingang, sondern ein Pull-Up an die Versorgungsspannung.

01:23:55.430 --> 01:24:00.190
Ich habe quasi hier immer die Versorgungsspannung durch den Pull-Up

01:24:00.190 --> 01:24:04.950
-Widerstand ausgegeben und nur, wenn die Eingabe wirklich sagt, die

01:24:04.950 --> 01:24:07.850
Ausgabe soll 0 sein, also wenn quasi eine 1 als Eingabe reinkommt,

01:24:08.310 --> 01:24:09.490
wird der Transistor schalten.

01:24:09.490 --> 01:24:13.470
Und der ist halt so implementiert, dass er stärker schaltet als der

01:24:13.470 --> 01:24:13.750
hier.

01:24:15.250 --> 01:24:19.290
So gesehen würde bei einer 1 das Ground-Signal ausgegeben werden, es

01:24:19.290 --> 01:24:20.250
würde nur 0 rauskommen.

01:24:20.730 --> 01:24:23.150
Dann hätte ich aber dauerhaften Stromfluss von hier,

01:24:23.230 --> 01:24:27.210
Versorgungsspannung, über Widerstand, über Transistor nach Ground.

01:24:27.530 --> 01:24:28.150
Das ist der Nachteil.

01:24:28.250 --> 01:24:30.950
Ich habe quasi den statischen Stromfluss die ganze Zeit.

01:24:33.290 --> 01:24:37.110
Gut, also das wäre die Variante, wie man eine NMOS-Speicherzelle bauen

01:24:37.110 --> 01:24:37.430
kann.

01:24:37.950 --> 01:24:41.730
Ich habe den N-Kanal-Transistor unten und einen Widerstand, den ich

01:24:41.730 --> 01:24:44.130
letztendlich auch als N-Kanal-Transistor aufbaue.

01:24:46.790 --> 01:24:53.130
Gut, schauen wir uns die Demos, also die dynamischen Speicher ganz

01:24:53.130 --> 01:24:53.810
kurz an.

01:24:54.450 --> 01:24:55.770
Aber das werden wir auf jeden Fall wiederholen müssen.

01:24:56.910 --> 01:25:00.910
Was wir hier haben, ist eine Kapazität.

01:25:02.190 --> 01:25:04.230
Ignorieren wir mal das rechte Bild, gucken wir einfach mal hier, das

01:25:04.230 --> 01:25:06.690
ist ein Kondensator, der speichert Ladung.

01:25:06.690 --> 01:25:11.090
Und jetzt benutzen wir diesen Kondensator, um uns den Speicherzustand

01:25:11.090 --> 01:25:11.670
zu merken.

01:25:11.990 --> 01:25:14.910
Gerade eben hatten wir zwei rückgekoppelte Inverter benutzt, um uns

01:25:14.910 --> 01:25:16.150
den Speicherzustand zu laden.

01:25:16.690 --> 01:25:19.510
Die waren stabil, die haben das stabil gehalten, solange

01:25:19.510 --> 01:25:20.710
Versorgungsspannung angelegen hat.

01:25:21.130 --> 01:25:22.650
Jetzt benutzen wir einen Kondensator dafür.

01:25:22.650 --> 01:25:28.250
Das heißt, mit dem Transistor können wir den Kondensator mit der

01:25:28.250 --> 01:25:31.470
Leitung hier verbinden und dann können wir quasi einmal verbinden zum

01:25:31.470 --> 01:25:31.950
Schreiben.

01:25:32.530 --> 01:25:35.450
Beim Schreiben, wenn ich zum Beispiel eine Null reinschreiben möchte,

01:25:35.850 --> 01:25:39.290
dann würden hier Elektronen ankommen, würden hier in den Kondensator

01:25:39.290 --> 01:25:42.530
reingeladen werden, dann würde der abgetrennt werden, also der trennt

01:25:42.530 --> 01:25:44.840
wieder, dann habe ich den Kondensator hier immer noch aufgeladen.

01:25:44.840 --> 01:25:48.920
Aufgeladen im Sinne von, hier ist der Dauerabfluss angelegt, hier habe

01:25:48.920 --> 01:25:52.020
ich jetzt ganz viele Elektronen, die vom... naja, ganz viele... das

01:25:52.020 --> 01:25:53.880
sind ganz viele, das sind eigentlich ziemlich viele, oder?

01:25:54.460 --> 01:25:58.140
Ganz viele Elektronen hier aufgeladen, draufliegen und später, wenn

01:25:58.140 --> 01:26:02.020
ich ihn lesen will, dann lege ich halt eben hier nicht eine Spannung

01:26:02.020 --> 01:26:06.200
an, die schreiben soll, sondern ich schließe den Transistor, damit

01:26:06.200 --> 01:26:10.360
können die Elektronen hier rausfließen und ich prüfe einfach, kommen

01:26:10.360 --> 01:26:13.560
da Elektronen an, dann waren offensichtlich welche hier drauf, dann

01:26:13.560 --> 01:26:14.620
war er vorher aufgeladen.

01:26:14.620 --> 01:26:18.600
Oder kommen hier keine Elektronen an, naja, dann war er halt nicht

01:26:18.600 --> 01:26:20.980
aufgeladen, dann war da der andere Wert gespeichert.

01:26:21.380 --> 01:26:26.600
Also beim Lesen entlade ich den Kondensator und je nachdem, ob ich da

01:26:26.600 --> 01:26:29.940
Elektronen rausholen kann oder nicht, kann ich dann sehen, waren da

01:26:29.940 --> 01:26:32.380
welche gespeichert, war der eine Wert oder der andere Wert

01:26:32.380 --> 01:26:34.640
gespeichert, Elektronen vorhanden oder nicht vorhanden.

01:26:34.640 --> 01:26:36.940
Das ist so die grundsätzliche Idee.

01:26:37.420 --> 01:26:38.920
Dann gucken wir uns das nächste Mal noch ein bisschen ausführlicher

01:26:38.920 --> 01:26:39.160
an.

01:26:39.480 --> 01:26:44.120
Wir haben Probleme, weil so groß ist die Zahl eigentlich gar nicht.

01:26:45.040 --> 01:26:47.200
Die driften weg, die Elektronen.

01:26:47.260 --> 01:26:49.940
Sprich, wenn wir den einfach nur in Ruhe lassen, den Kondensator, die

01:26:49.940 --> 01:26:53.140
Elektronen verschwinden von ganz alleine und nach ein paar Sekunden

01:26:53.140 --> 01:26:54.140
ist der quasi leer.

01:26:54.560 --> 01:26:59.200
Also ich muss den quasi dauernd wieder aufladen, auch nachdem ich ihn

01:26:59.200 --> 01:27:01.500
gelesen habe, sind die Elektronen auf jeden Fall weg.

01:27:01.500 --> 01:27:04.160
Also wenn ich ihn gelesen habe, muss ich ihn danach wieder schreiben.

01:27:05.300 --> 01:27:09.440
Das gucken wir uns dann nächste Woche nochmal genauer an und dann noch

01:27:09.440 --> 01:27:12.080
verschiedene andere Arten, wie zum Beispiel DEREM-Speicher heute

01:27:12.080 --> 01:27:12.780
aufgebaut sind.

01:27:13.080 --> 01:27:14.060
Vielen Dank und bis nächste Woche.

