Ich hatte ja eine Antwort versprochen und die möchte ich nicht schuldig bleiben.
Kann ein fünfzig Jahre alter Mikroprozessor (der originale MOS6502 ca.1976) schneller arbeiten als ein deutlich modernerer AVR ATmega32u4 (oder ähnlicher Typ)? Der wurde irgendwann ab 2008 released.
Der AVR darf mit 16 MHz getaktet werden, der MOS6502 kann nur 1 MHz.
Die sehr einfache und geradlinige Aufgabe ist die Folgende:
Berechne alle Fibonacci Zahlen < 10^80. Das sind die ersten 382 Zahlen.
1
#!/usr/bin/python3
2
# -*- coding: UTF-8 -*-
3
# vim: fileencoding=utf-8: ts=4: sw=4: expandtab:
4
value1,value2=0,1
5
foriinrange(383):
6
value1,value2=value2,value1+value2
7
print(f'┃{value2:080}┃')
10^80 deshalb, weil der gute alte Commodore CBM8032 einen 80×25 Bildschirm sein Eigen nennt und man so jede Fibonacci-Zahl in einer eigenen Zeile darstellen kann.
Außerdem sind die Zahlen derart groß, dass man nicht mehr mit den üblichen Mitteln arbeiten kann. Und zumindest soweit mir bekannt ist, unterstützt auch kein C Compiler ein uint272_t. (ceil(ln(10)/ln(2)×80÷8)×8)
Die Wahl der Waffen/Programmiersprache ist wahlfrei, es wird aber wie beim MOS6502 vermutlich auf Assembler hinaus laufen.
Wie ist eure Einschätzung?
Kann ein CBM8032 so etwas?
Wie lange braucht der CBM8032 bei 1 MHz um die 382 Zahlen zu berechnen und darzustellen?
Und fast noch wichtiger, kann ein viel modernerer ATmega32u4 das (deutlich) schneller?
Ein Video des Programmlaufes auf dem Commodore ist bereits erstellt, allerdings ist das mp4 um die 10MB groß.
Das werde ich später einstellen.
Dazu ebenfalls eine »fibonacci.p00« Datei.
Damit kann es jeder selbst laufen lassen und überprüfen. (Läuft auch auf dem VICE)
Und natürlich die korrekten Ergebnisse mit der Ausgabe des Python Programms verifizieren.
Wenn man genug Abstraktion/Virtualisierung/Emulation/API Schnittstellen... dazwischen packt, bekommt man sicher auch einen Epyc/i7 etc auf 8086 Geschwindigkeit.
Würds gern testen, hab aber leider keinen C-128er mehr. Ich hab aber vor vielen Jahren was ähnliches gemacht, nämlich die aktuelle Gewinnzahlposition aus den damals noch 13 Mio möglichen Lottosechser anzuzeigen und die möglichen Treffer aus dem Faber Systembuch zu berechnen. Dafür hab ich die Bildschirmausgabe abgeschaltet und erst nach Treffer wieder aktiviert. Fazit: das Assembler Programm des C64 war ein vielfaches schneller als das äquivalente QBasic Programm auf einem 486er PC. Ich würd also so vorgehen: erst mal alle Zahlen berechnen und dann in den Bildschirmspeicher schieben...
Spann mich net auf die Folter, schafft das der 6502?
Schätzung:
AVR32:
4x schneller wegen 32bit
16x schneller wegen Mhz
3x schneller wegen IPC
10^80 => 265bit =>34byte
Dementsprechend 34 add/adcs pro Zahl
382x das ganze, dazu noch overhead vom SRAM schreiben/lesen
34x382x z.B. 10cyclen Overhead für Read/Write
=>130000 Zyklen für den 6502 oder ca. 1/10sec
beim AVR32 entsprechend ca. 200x schneller oder 1/2 msec
Kann ein fünfzig Jahre alter Mikroprozessor (der originale MOS6502
ca.1976) schneller arbeiten als ein deutlich modernerer AVR ATmega32u4
(oder ähnlicher Typ)?
Wenn man den AVR ins Knie schießt und per Hand taktet.
Der wurde irgendwann ab 2008 released.
Der AVR darf mit 16 MHz getaktet werden, der MOS6502 kann nur 1 MHz.
Hat schon verloren. Aber der Heldentod kommt wieder in Mode ;-)
10^80 deshalb, weil der gute alte Commodore CBM8032 einen 80×25
Bildschirm sein Eigen nennt und man so jede Fibonacci-Zahl in einer
eigenen Zeile darstellen kann.
Hehe.
Außerdem sind die Zahlen derart groß, dass man nicht mehr mit den
üblichen Mitteln arbeiten kann. Und zumindest soweit mir bekannt ist,
unterstützt auch kein C Compiler ein uint272_t.
(ceil(ln(10)/ln(2)×80÷8)×8)
Kann man ja manuell mit BCD berechnen. Sollte einfacher und schneller sein als immer in binär und dann immer umrechnen.
Die Wahl der Waffen/Programmiersprache ist wahlfrei, es wird aber wie
beim MOS6502 vermutlich auf Assembler hinaus laufen.
Das kann auch ne Turingmaschine. Alles nur eine Frage der Rechenzeit.
Wie ist eure Einschätzung?
Kann ein CBM8032 so etwas?
Ja.
Wie lange braucht der CBM8032 bei 1 MHz um die 382 Zahlen zu berechnen
und darzustellen?
Geschätzt deutlich weniger als 1s (in Assembler). Ich mein es sind 382 Additionen einer 80stelligen BCD Zahl. So wild ist das nicht. Die Hardcorevariante rechnet das gleich im Videospeicher mit PETSCII-Code!
macht ~2600 Takte / Zahl
Und fast noch wichtiger, kann ein viel modernerer ATmega32u4 das
(deutlich) schneller?
Sicher, denn der ist höher getaktet, braucht weniger Takte/Speicherzugriff und kann, wenn man weiß was man tut, mehrere Stellen in Registern halten und berechnen.
Ein Video des Programmlaufes auf dem Commodore ist bereits erstellt,
allerdings ist das mp4 um die 10MB groß.
Aber wenn dein 6502 über 64k RAM verfügen kann, kann er den ATmega, der
wenig RAM hat, schlagen.
Nicht mal dann. Die beiden Zahlen brauchen 34 Byte in Binärkodierung oder 40 in BCD, macht max. 80 Byte. Die hat sogar ein ATtiny13. Addieren und Ausgeben über UART, fertig.
Aber mal wieder ein sehr gehaltvoller Beitrag von dir!
Kann ein CBM8032 so etwas?
Wie lange braucht der CBM8032 bei 1 MHz um die 382 Zahlen zu berechnen
und darzustellen?
Bei solchen Aufgaben geht die Zeit hauptsächlich für die Bildschirmausgabe drauf. Wenn man das normal ausgibt, dann muss ja nach der 25. Zeile gescrollt werden. Dazu werden die 4KB Bildschirmspeicher (ich nehme an, das ist wie beim C64 mit 1Byte Zeichen und 1 Byte Attribut) fast vollständig gelesen und wieder geschrieben. Das dauert viel länger als die Rechnung.
Man könnte natürlich noch tricksen und z.B. alle Zahlen in ASCII hintereinander in den Speicher schreiben und dann den Offset des Bildschirmspeichers verschieben, aber das ist ein wilder Hack.
Man könnte natürlich noch tricksen und z.B. alle Zahlen in ASCII
hintereinander in den Speicher schreiben und dann den Offset des
Bildschirmspeichers verschieben, aber das ist ein wilder Hack.
Nö, direkt in den Videospeicher ab 1024 schreiben!
Ich kann mir denken, worauf du hinaus willst. Der 6502 hat ein
bestimmtes Feature, das der AVR nicht bzw. nur sehr eingeschränkt hat.
Ich glaube aber nicht, dass dieses Feature dem 6502 gegenüber dem
deutlich höher getakteten AVR zu Sieg verhilft.
Wie lange braucht der CBM8032 bei 1 MHz um die 382 Zahlen zu berechnen
und darzustellen?
Und fast noch wichtiger, kann ein viel modernerer ATmega32u4 das
(deutlich) schneller?
Vielleicht solltest du auch noch definieren, was du unter "berechnen"
und "darstellen" verstehst.
Zählt das Lesen einer bis zu 80-stelligen Zahl aus dem Flash und die
anschließende Addition von 0 schon als "berechnen"? Vermutlich nicht.
Sind Look-Up-Tabellen zur Beschleunigung von Berechnungen erlaubt? Wenn
ja, bis zu welcher Größe?
Vermutlich sind aber gar keine Tabellen erforderlich, um den 6502 zu
schlagen.
Der AVR hat im Gegensatz zum CBM kein integriertes Display. Somit
braucht er streng genommen ewig, um die Ergebnisse darzustellen. Welche
Optionen gestehst du dem AVR zu, die Ergebnisse dennoch anzuzeigen?
so jede Fibonacci-Zahl in einer eigenen Zeile darstellen kann.
Wie genau erfolgt die Ausgabe in deinem 6502-Programm? Was passiert,
wenn die 25ste Zeile erreicht ist? Wird der Bildschirm dann um eine
Zeile hochgescrollt? Das Scrollen alleine würde ja schon sehr viel mehr
Zeit kosten als die eigentliche Berechnung (s. Beitrag von Markus).
Man könnte natürlich noch tricksen und z.B. alle Zahlen in ASCII
hintereinander in den Speicher schreiben und dann den Offset des
Bildschirmspeichers verschieben, aber das ist ein wilder Hack.
Nö, direkt in den Videospeicher ab 1024 schreiben!
Das habe ich vorausgesetzt. Aber das Scrollen bleibt ja trotzdem. Außer, wenn man eben den Start des Bildschirmspeichers verschiebt. Dann scrollt man auch, aber eben ohne Kopierorgien.
Aber das mit dem Scrollen habe ich halt so angenommen. Man kann natürlich auch einfach immer auf die gleiche Stelle schreiben. Das verbietet die Aufgabe nicht. Wenn man aber schneller als die Bildwiederholfrequenz ist, dann werden gar nicht alle Zahlen dargestellt. Gilt das dann noch? Oder einfach am Ende des Bildschirms wieder oben anfangen.
Letztendlich ist die Aufgabe bzgl. der Ausgabe schlecht gestellt.
Ich kann mir denken, worauf du hinaus willst. Der 6502 hat ein
bestimmtes Feature, das der AVR nicht bzw. nur sehr eingeschränkt hat.
;-)
Vielleicht solltest du auch noch definieren, was du unter "berechnen"
und "darstellen" verstehst.
Wirklich komplett und von Grund auf berechnen. Keine Tabellen, kein Look-up.
Der AVR hat im Gegensatz zum CBM kein integriertes Display. Somit
braucht er streng genommen ewig, um die Ergebnisse darzustellen. Welche
Optionen gestehst du dem AVR zu, die Ergebnisse dennoch anzuzeigen?
Wir hatten das damals so vereinbart, das die auszugebenden Daten einzeln Zeilenweise als fertiger String im Speicher bereit liegen müssen. Also Berechnung und Ausgabe völlig getrennt. Die Rechner-Architekturen waren damals einfach viel zu unterschiedlich. Und so konnten wir wahlweise die Ausgabe unterdrücken und die Differenz messen.
Also wären ein angeschlossener Lochstreifen-Stanzer oder ein zig-MBit UART USB Interface gleich gut.
Wie genau erfolgt die Ausgabe in deinem 6502-Programm? Was passiert,
wenn die 25ste Zeile erreicht ist? Wird der Bildschirm dann um eine
Zeile hochgescrollt?
Fällt ja alles unter Ausgabe. Aber um's aufzuhübschen, zwei Drittel des Bildschirms werden fortlaufend beschrieben und dann wieder von oben überschrieben. So kann man den Fortschritt verfolgen und dennoch die letzten ca. 15 Werte begutachten.
Darunter dann die Ergebnisse.
Die Ausgabe musste ich allerdings komplett neu schreiben, nichts was die Commodore ROMs oder die Microsoft ROMs bieten kommen auch nur halbwegs in den erträglichen Bereich. Da braucht man selbst mit Assembler einen Abreißkalender.
Letztendlich ist die Aufgabe bzgl. der Ausgabe schlecht gestellt.
Da hast du Recht, hätte ich präziser sein müssen. Eigentlich geht es aber um die komplette Berechnung inklusive Vorbereitung zur Ausgabe.
Ich habe die Ausgabe nur zur Visualisierung mit hinein genommen.
Wir hatten das damals so vereinbart, das die auszugebenden Daten einzeln
Zeilenweise als fertiger String im Speicher bereit liegen müssen.
Mit "String" meist du einen ASCII-String (also eine Folge von Bytes in
0x30..0x39), der (bei aktivierter Ausgabe) ohne weitere Konvertierung in
den Bildspeicher kopiert werden kann?
Mit "String" meist du einen ASCII-String (also eine Folge von Bytes in
0x30..0x39), der (bei aktivierter Ausgabe) ohne weitere Konvertierung in
den Bildspeicher kopiert werden kann?
Der AVR hat im Gegensatz zum CBM kein integriertes Display. Somit
braucht er streng genommen ewig, um die Ergebnisse darzustellen. Welche
Optionen gestehst du dem AVR zu, die Ergebnisse dennoch anzuzeigen?
Wir hatten das damals so vereinbart, das die auszugebenden Daten einzeln
Zeilenweise als fertiger String im Speicher bereit liegen müssen. Also
Berechnung und Ausgabe völlig getrennt.
Na Vorsicht! Es gibt das DREI Aufgaben!
Neue Zahl berechnen (welches internes Format auch immer)
Zahl in ASCII umwandlen
String ausgeben
Der 6502 hat da auch bei gleichem Takt keine Chance, der AVR kann viele Instruktionen in einem Takt ausführen, die der 6502 erst aus dem Speicher lesen muss.
384 Zahlen mit je 34 Bytes sind 13.056, das bekommt ein ATMega1284 komplett in seine 16kB RAM hinein.
Die 383 Fibonacci-Zahlen haben zusammen 15506 Ziffern, wenn man – wie in
Norberts Python-Vorlage – die ersten beiden (0 und 1) weglässt.
Jede dieser Ziffern muss irgendwann als ASCII-Zeichen in den Speicher
geschrieben werden. Das Schreiben eines Bytes dauert beim 6502
mindestens 3 Zyklen (STA auf Nullseite). Das Schreiben aller 383 Strings
dauert also bei der Taktfrequenz von 1 MHz mindestens
15506 · 3 µs ≈ 46,5 ms
Hinzu kommt natürlich noch die eigentliche Berechnung, die sicher
deutlich länger dauert.
Ich werde morgen einen Code für den ATmega32U4 posten, der bei 16 MHz
für die Berechnung und das Schreiben der Zahlen als ASCII-Strings
weniger als 20 ms braucht.
Da wirst Du das Problem bekommen, daß das Darstellen der Zahlen als ASCII und vor allem die Datenübertragung deutlich mehr Zeit benötigt, als die Berechnung.
Selbst bei 1Mbit mit dem UART braucht ein Byte (9 Bit bei 8N1) mindestens 9µs für die Übertragung. In den 20ms, die Du Dir als Ziel gesetzt hast, bekommst Du nur gut 2,2kB übertragen. Das reicht bei weitem nicht für alle 384 Zahlen.
Wenn man die Zahlen von Falk mal zugrunde legt, dauert die Übertragung aller Zahlen (mit Durchnummerierung) 2700ms. Bei 115kbit und 8N1 sind das 34.560 Bytes. Bei 1Mbit 8N1 würde allein diese Übertragung 311ms dauern.
Wenn Du mit Deinen 15506 Ziffern (ohne Textformatierung) Recht hast, landest immer noch bei grob überschlagen 150ms nur für die Übertragung bei 1Mbit.
Bei Deinem Beispiel hast Du auch vergessen, daß der 6502 meiner Kenntnis zwar auf der Zero Page einigermaßen schnell ist, aber weder passen alle Ziffern in 256 Byte Zero Page, noch liegt dort der Bildschirmspeicher.
Mich würde mal interessieren, wie lange der C64 in Basic dafür braucht.
Kann man das noch in Stunden messen?
Wie ist eure Einschätzung?
Kann ein CBM8032 so etwas?
Norbert hat hier vermutlich den BCD-Mode des 6502 herausgekramt und freut sich jetzt darüber, dass der AVR dabei versagt, die interne Binärzahl in eine dezimale ASCII-Ausgabe zu konvertieren.
Allerdings kann man ja auch auf dem AVR den BCD-Mode emulieren, man hat ja deutlich mehr IPC.
Mich würde mal interessieren, wie lange der C64 in Basic dafür braucht.
Kann man das noch in Stunden messen?
Meine Schätzung. Wenn wir mal grob von 10 Basicbefehlen/s ausgegehen und ca. 10000 davon pro Fibonaccizahl ansetzen, macht das irgendwas um die 384.000s bzw. 106,6h. Ist jetzt aber SEHR grob über den Daumen gepeilt. Vermutlich geht es schneller.
Ich werde morgen einen Code für den ATmega32U4 posten, der bei 16 MHz
für die Berechnung und das Schreiben der Zahlen als ASCII-Strings
weniger als 20 ms braucht.
Da bin ich mal gespannt! Ok, in handgeklöppeltem Assembler könnte das klappen.
Der AVR-code ist nicht getestet. Ich wollte nur einmal schauen, ob LLMs inzwischen auch AVR-Assembler können. Anscheinend ist das der Fall.
Ich habe zunächst das C-programm erzeugt und das als Vorlage für die Assemblerimplementierung genetzt.
Man könnte durch mehr loop-unrolling noch ein paar Taktzyklen herausholen. Bin mir nicht sicher, ob nibble-packing viel hilft, da der AVR ja sowieso recht schnellen Speicherzugriff hat.
1
; Start with carry=0 path
2
rjmp carry0_path ; Enter the loop with carry=0
3
4
carry1_path:
5
; This is the path when carry=1 from previous iteration
6
ld temp1, -Z ; Load previous[j] and decrement Z
7
ld temp2, -Y ; Load current[j] and decrement Y
8
add temp1, temp2 ; Add current digit
9
inc temp1 ; Add carry=1
10
11
; Check for decimal overflow
12
cpi temp1, 10 ; Compare with 10
13
brlo store_no_carry ; If < 10, no new carry
14
15
carry_with_overflow:
16
; Handle carry case
17
subi temp1, 10 ; Subtract 10
18
st Z, temp1 ; Store result
19
20
dec inner_cnt ; Decrement counter
21
brne carry1_path ; If counter not zero, continue with carry=1
22
rjmp inner_done ; Exit if counter is zero
23
24
carry0_path:
25
; This is the path when carry=0 from previous iteration
26
ld temp1, -Z ; Load previous[j] and decrement Z
27
ld temp2, -Y ; Load current[j] and decrement Y
28
add temp1, temp2 ; Add current digit (no carry to add)
29
30
; Check for decimal overflow
31
cpi temp1, 10 ; Compare with 10
32
brsh carry_with_overflow ; If >= 10, reuse the common overflow code
33
34
; Fall through to common store with no carry
35
36
store_no_carry:
37
st Z, temp1 ; Store result
38
39
dec inner_cnt ; Decrement counter
40
brne carry0_path ; If counter not zero, continue with carry=0
Das ist eine spannende Frage, die einen direkten Vergleich der beiden Mikroprozessoren mit einer konkreten Aufgabe, der Berechnung der Fibonacci-Zahlen, anstellt. Um diese Frage zu beantworten, müssen wir uns sowohl die architektonischen Unterschiede als auch die Geschwindigkeit bei der Berechnung anschauen.
Grundlegende Unterschiede zwischen MOS6502 und AVR ATmega32u4:
MOS6502 (1976):
Taktfrequenz: 1 MHz.
8-Bit-Architektur.
Kein Hardware-Divider, also alle Divisionen und viele Berechnungen müssen durch Software erfolgen.
Relativ einfache und geradlinige Befehlssätze.
AVR ATmega32u4 (2008):
Taktfrequenz: 16 MHz (oder mehr, abhängig von der Konfiguration).
8-Bit-Architektur mit erweiterten Funktionen und Optimierungen.
Hardware-Divider und viele Optimierungen, um Berechnungen zu beschleunigen.
Neuere Befehlssätze und komplexere Architektur.
Fibonacci-Zahlen Berechnung:
Die Fibonacci-Zahlen sind eine Folge, in der jede Zahl die Summe der beiden vorherigen ist. Die Formel lautet:
[ F(n) = F(n-1) + F(n-2) ]
Für diese Aufgabe möchten wir die ersten 382 Fibonacci-Zahlen berechnen, die alle kleiner als (10^{80}) sind. Diese Zahlen wachsen schnell, und die Herausforderung liegt darin, mit sehr großen Ganzzahlen zu arbeiten.
Schritt 1: Berechnung der Fibonacci-Zahlen
Eine effiziente Methode zur Berechnung der Fibonacci-Zahlen ist die iterative Berechnung, bei der nur die letzten beiden Zahlen der Folge gespeichert werden. Für sehr große Zahlen wird eine Bibliothek für arbiträr große Ganzzahlen benötigt.
Die wichtigsten Schritte für beide Prozessoren sind:
Initialisierung der ersten beiden Zahlen der Fibonacci-Folge.
Iterative Berechnung der nächsten Zahlen, bis die Grenze von (10^{80}) überschritten wird.
Schritt 2: Vergleich der Prozessoren
Obwohl der AVR ATmega32u4 mit 16 MHz getaktet wird, was mehr als 16 Mal schneller ist als der MOS6502 mit nur 1 MHz, ist es wichtig, die Optimierungen in der Architektur zu berücksichtigen. Der AVR hat moderne Hardwareunterstützung, z. B. für Divisionen und große Ganzzahlenoperationen, was ihn wesentlich effizienter macht als der MOS6502.
Berechnungsbeispiel
Hier ist ein Python-Skript, das die Fibonacci-Zahlen berechnet. Es kann als eine grobe Referenz für die Leistung beider Prozessoren dienen, da die Prozessoren in der Praxis natürlich ganz unterschiedliche Maschinen sind und wir uns nur auf die theoretische Geschwindigkeit stützen können:
1
deffibonacci_up_to(limit):
2
fibs=[0,1]
3
whileTrue:
4
next_fib=fibs[-1]+fibs[-2]
5
ifnext_fib>=limit:
6
break
7
fibs.append(next_fib)
8
returnfibs
9
10
# Definiere die Obergrenze (10^80)
11
limit=10**80
12
fibs=fibonacci_up_to(limit)
13
14
# Gebe die ersten 382 Fibonacci-Zahlen aus
15
fori,fibinenumerate(fibs[:382]):
16
print(f"F({i}) = {fib}")
Schritt 3: Laufzeitbewertung
MOS6502:
Da der MOS6502 eine einfachere Architektur hat und mit nur 1 MHz arbeitet, wird das Berechnen der Fibonacci-Zahlen sehr langsam sein, besonders bei großen Zahlen. Es könnte mehrere Minuten oder sogar Stunden dauern, um 382 Fibonacci-Zahlen zu berechnen.
AVR ATmega32u4:
Der AVR mit 16 MHz wird deutlich schneller sein, da er mehr Rechenleistung pro Takt ausführen kann und moderne Optimierungen bietet. Die Berechnungen sollten in wenigen Sekunden oder höchstens Minuten abgeschlossen sein, selbst bei der Berechnung von Fibonacci-Zahlen mit sehr großen Werten.
Fazit:
Der AVR ATmega32u4 wird sicherlich viel schneller sein als der MOS6502 bei der Berechnung der Fibonacci-Zahlen, selbst wenn der MOS6502 mit der maximalen Frequenz von 1 MHz arbeitet. Die zusätzliche Rechenleistung und die Hardwareoptimierungen des AVR machen ihn deutlich schneller bei der Berechnung dieser Folge.
Wenn du noch genauere Details zur Berechnung oder eine genauere Abschätzung der Rechenzeiten auf beiden Prozessoren möchtest, kann ich dir bei Bedarf auch eine Simulation oder weitere Informationen zu diesen Prozessoren und ihrer Performance bei der Fibonacci-Berechnung geben!
; Fibonacci-Berechnung für den MOS6502
; Berechnet die ersten Fibonacci-Zahlen und speichert sie im RAM
1
.org $8000 ; Startadresse des Programms
2
LDX #$00 ; Setze X (Fibonacci Index) auf 0
3
LDY #$00 ; Setze Y (Fibonacci-Zahl 0) auf 0
4
LDA #$01 ; Lade A mit 1 (erste Fibonacci-Zahl)
start_fib:
STA $0200,X ; Speichere die aktuelle Fibonacci-Zahl in RAM ($0200 + X)
Cpx #$0C ; Stoppe nach 12 Fibonacci-Zahlen (Du kannst das anpassen)
BEQ done ; Wenn 12 Fibonacci-Zahlen erreicht, Ende
1
LDA $0200,X ; Lade die aktuelle Fibonacci-Zahl in A
2
LDY $0200,X ; Lade die vorherige Fibonacci-Zahl in Y
3
CLC ; Clear Carry
4
ADC $0200,X ; A = A + Y (F(n) = F(n-1) + F(n-2))
5
STA $0200,X ; Speichere die neue Fibonacci-Zahl in RAM
6
7
INX ; Erhöhe X für den nächsten Index
8
BNE start_fib ; Wiederhole den Berechnungsloop, solange nicht fertig
done:
BRK ; Beende das Programm
und
; Fibonacci-Berechnung für den AVR ATmega32u4
; Berechnet die ersten Fibonacci-Zahlen und speichert sie im SRAM
.include "m32u4def.inc" ; AVR Header für ATmega32u4
1
.org 0x00 ; Startadresse (Reset-Vector)
2
rjmp main ; Springe zur Hauptfunktion
main:
ldi r16, 0 ; Setze r16 (erste Fibonacci-Zahl) auf 0
ldi r17, 1 ; Setze r17 (zweite Fibonacci-Zahl) auf 1
ldi r18, 0x20 ; Speicheradresse für die Fibonacci-Zahlen im SRAM (z.B. $20)
1
; Berechnung der ersten 10 Fibonacci-Zahlen
2
; Die Berechnung geht durch eine Schleife und speichert die Zahlen im SRAM
3
ldi r19, 10 ; Anzahl der Fibonacci-Zahlen, die wir berechnen wollen (z.B. 10)
fibonacci_loop:
st X+, r16 ; Speichere Fibonacci-Zahl (r16) im SRAM
mov r20, r16 ; Kopiere r16 in r20 (für Zwischenspeicherung)
add r16, r17 ; r16 = r16 + r17 (Berechne Fibonacci)
mov r17, r20 ; Setze r17 auf den alten Wert von r16 (n-1)
1
dec r19 ; Verringere die Anzahl der verbleibenden Zahlen
2
brne fibonacci_loop ; Wenn nicht alle Zahlen berechnet sind, wiederhole die Schleife
Das ist eine spannende Frage, die einen direkten Vergleich der beiden
Was soll der Bullshit? LLMs zu nutzen ist sinnvoll, aber man sollte damit auch vernünftig umgehen. Einfach Slop ins Forum zu posten erzeugt unnötiges Rauschen. Es kopiert ja auch nicht jeder seine debug-logs ins forum.
Der Code oben ist falsch und ignoriert die Aufgabenstellung.
Der Code oben ist falsch und ignoriert die Aufgabenstellung.
Das könnte man ja noch anpassen lassen.
Wollte damit nur sagen, das Foren durch ChatGPT und co weitesgehend ausgedient haben, da man di e meisten Fragen heute dort schnell beantwortetn kann, sei des die Berühmte LED mit Vorwiderstand oder andere Dinge ohne das provozierende Fragen dazwischen auftauchen.
Und das funktioniert inzwischen sehr gut und nächstes jahr nahezu Perfekt als Forumsersatz
Der Code oben ist falsch und ignoriert die Aufgabenstellung.
Das könnte man ja noch anpassen lassen.
Wollte damit nur sagen, das Foren durch ChatGPT und co weitesgehend
ausgedient haben, da man di e meisten Fragen heute dort schnell
Du hast gerade gezeigt, dass das nicht der Fall ist, denn die Antwort besteht nur aus oberflächlichem Bullshit, der die Kernprobleme ignoriert.
Man kann allerdings durch gezieltes Prompting ein geeignetes Programm erzeugen (s.O.). Ein wenig denken musste ich schon noch, um den Lösungsansatz vorzuschlagen :)
Außerdem ist es sinnfrei, komplette LLM Antworten in ein Forum zu kopieren. Oder kopierst Du auch komplette google-suchantworten?
Wollte damit nur sagen, das Foren durch ChatGPT und co weitesgehend
ausgedient haben, da man di e meisten Fragen heute dort schnell
beantwortetn kann,
Im Moment habe die Foren noch nicht ausgedient, da ChatGPT die Frage zwar beantwortet, aber eher als Allgemeinplatz.
Die Frage, ob ein 6502 unter bestimmten Voraussetzungen schneller sein kann als ein Atmega erfordert ein Verständnis von sehr speziellen Zusammenhängen, die ChatGPT nicht hat.
Die Verwendung der BCD Arithmetik-Befehle als Beschleuniger hat ChatGPT nicht auf dem Schirm, einfach weil sich's im Internet nicht so findet ( oder so speziell ist, dass es ChatGPT überlesen hat).
Man muss bloss das sinnlose BCD weglassen und direkt 1 byte pro Dezimalstelle nutzen. Statt Addieren kann man auch 2 x 2 (unterschiedliche, je nach Übertrag) 10 x 16 Tabellen nutzen: Summenziffer und Übertrag. Den Offset von '0' kann man bei der Ausgabe draufklatschen.
Das könnte man ja noch anpassen lassen.
Wollte damit nur sagen, das Foren durch ChatGPT und co weitesgehend
ausgedient haben, da man di e meisten Fragen heute dort schnell
beantwortetn kann, sei des die Berühmte LED mit Vorwiderstand oder
andere Dinge ohne das provozierende Fragen dazwischen auftauchen.
Und das funktioniert inzwischen sehr gut und nächstes jahr nahezu
Perfekt als Forumsersatz
Ok, mir ist (selbst-gedacht) noch eine Idee gekommen, wie man auf dem AVR die BCD-Mode Geschwindigkeit erreichen kann.
Es werden zwei Dezimalstellen pro byte gespeichert (d.h. 0-99). Dadurch kann der AVR das array mit (fast) genau so wenig Befehlen wie der 6502 bearbeiten und man erreicht die gleiche Packungsdichte von zwei Dezimalstellen pro Byte.
Um die zwei Dezimalstellen pro byte zu extrahieren, kann man eine lookup-tabelle nutzen.
Code anbei in C und avr assembler.
Die Ausgabe über UART ist auf dem AVR natürlich sehr limitierend. Ist natürlich die Frage, ob das ein fairer Vergleich zu dem CBM-Screenmode ist...
Taktfrequenz: 16 MHz (oder mehr, abhängig von der Konfiguration).
8-Bit-Architektur mit erweiterten Funktionen und Optimierungen.
Hardware-Divider und viele Optimierungen, um Berechnungen zu
beschleunigen.
Falsch. Der hat nur einen Multiplikator drin. Es ist KEIN 8051! ;-)
Neuere Befehlssätze und komplexere Architektur.
Jaja, Laberrababer.
Die Plappertante ChatGPT hat mal wieder heiße Luft erzeugt, die gut klingt, aber löchrig wie ein Schweizer Käse ist.
Obwohl der AVR ATmega32u4 mit 16 MHz getaktet wird, was mehr als 16
Mal schneller ist als der MOS6502 mit nur 1 MHz, ist es wichtig, die
Optimierungen in der Architektur zu berücksichtigen. Der AVR hat moderne
Hardwareunterstützung, z. B. für Divisionen und große
Falsch.
Da der MOS6502 eine einfachere Architektur hat und mit nur 1 MHz
arbeitet, wird das Berechnen der Fibonacci-Zahlen sehr langsam sein,
besonders bei großen Zahlen. Es könnte mehrere Minuten oder sogar
Stunden dauern, um 382 Fibonacci-Zahlen zu berechnen.
Apfelmus ist Mus aus Äpfeln.
AVR ATmega32u4:
Der AVR mit 16 MHz wird deutlich schneller sein, da er mehr
Rechenleistung pro Takt ausführen kann und moderne Optimierungen bietet.
Die Berechnungen sollten in wenigen Sekunden oder höchstens Minuten
abgeschlossen sein, selbst bei der Berechnung von Fibonacci-Zahlen mit
sehr großen Werten.
ChatGPT ist optimal zum Erzeugen von Politikerreden!
Nö. hier emulierst du den BCD Modus. Mein Ansatz nutzt um Prinzip ein Basis100 System. Außerdem ist die Assemblerimplementierung deutlich effizienter. Schaue dir mal den Code an.
Ich werde morgen einen Code für den ATmega32U4 posten, der bei 16 MHz
für die Berechnung und das Schreiben der Zahlen als ASCII-Strings
weniger als 20 ms braucht.
Es sind laut avrtest 244897 Taktzyklen oder 15306 µs.
Ich hatte ja eine Antwort versprochen und die möchte ich nicht schuldig
bleiben.
Bist du aber!
Nachdem du min 2 CPI beim 6502 brauchst (fetch+execution) und der AVR min 1CPI brazcht, hast du am AVR teilweise 32 Zyklen Vorteil... Da könnte es sich glatt ausgehen dein 6502 ASM binary am AVR emulieren zu lassen!
Während ich das oben schrieb, habe ich schnell mal Google gefragt... (Wunder mich, dass die künstliche Dummheit nicht darauf gekommen ist...)
Der ATMega1284P bei 24mhz CLK schafft wirst case 1,9MHz 6502 code emulation... Also sollte das am 32u4 bei 16mhz immer noch mit 1,3MHz laufen (IIRC, sind das die selben cores).
Damit wird zumindest der Vergleich mit dem 1MHz 6502 schon ziemlich absurd.
Mich würde mal interessieren, wie lange der C64
in Basic dafür braucht. Kann man das noch in Stunden messen?
Meine Schätzung. Wenn wir mal grob
von 10 Basicbefehlen/s ausgegehen [..]
Na, ein wenig schneller war er meiner Erinnerung nach schon, bzw. es kam stark darauf an welche Befehle das waren und ob sowas wie Bildschirm scrollen weiter Zeit geklaut hat. Sowas wie Sprites über den Bildschirm schieben geht ruckelfrei, jedenfalls solange es nicht zu viele oder zu viele Achsen sind.
Ich würde mich aber wundern, wenn der C64 bereits so große Zahlen in Basic beherrschte. Wahrscheinlich muss man die wieder atomar behandeln und sie sich selbst zusammensetzen.
Ein Vorteil könnte vielleicht sein, wenn man "Basic" ein wenig dehnt... man ist ja beim C64 noch Herr über die Maschine. Heißt, man kann die Zahlen mit Peek&Poke in einen von Basic gerade nicht benutzten Speicherbereich hineinschreiben, ohne daß die Kiste crasht. Vielleicht wäre das schneller als die reinen Basic-Variablen zu benutzen.
Die Frage, ob ein 6502 unter bestimmten Voraussetzungen schneller sein
kann als ein Atmega erfordert ein Verständnis von sehr speziellen
Zusammenhängen, die ChatGPT nicht hat.
Die sich aber im Kontext der Aufgabenstellung durch intensives Nachdenken von wenigen Millisekunden mit Nein beantworten lässt.
Selbst wenn der 6502 den ein- oder anderen Befehl hat, der auf einem AVR durch mehrere nachgebildet werden müssten, reicht alleine der Faktor 16 beim Takt für diese Aussage.
Ich kann mir denken, worauf du hinaus willst. Der 6502 hat ein
bestimmtes Feature, das der AVR nicht bzw. nur sehr eingeschränkt hat.
Aber:
Ich glaube aber nicht, dass dieses Feature dem 6502 gegenüber dem
deutlich höher getakteten AVR zu Sieg verhilft.
Die BCD-Addition geht zwar superschnell (4,5 Taktzyklen pro Ziffer inkl.
Laden und Speichern), aber die anschließende Umwandlung in einen
ASCII-String dauert IMHO mindestens 13,5 Zyklen/Ziffer, u.a. deswegen,
weil dem 6502 ein Nibble-Swap-Befehl fehlt. In Summe sind das – bei
vollständig ausgerollten Schleifen 18 Zyklen/Ziffer. Selbst bei gleicher
Taktfrequenz dürfte der 6502 trotz des BCD-Modus das Rennen immer noch
knapp verlieren. Das liegt u.a. auch daran, dass er etwa doppelt so
viele Zyklen pro Instruktion braucht als der AVR.
Angesichts seines Alters ist das aber überhaupt keine Schande. Da ich
auf einem Apple II programmieren gelernt habe (erst in Basic, dann in
Hex-Maschinencode, später in Assembler und schließlich in Pascal), bin
ich nach wie vor ein Fan des 6502 :)
Auf jeden Fall bin ich auf Norberts Code gespannt. Vielleicht hat er ja
noch irgendetwas in seiner Trickkisten, an das bisher noch keiner
gedacht hat.
Angesichts seines Alters ist das aber überhaupt keine Schande
Na ja, peinlich ist eher, dass der AVR obwohl 40 Jahre jünger nur etwas schneller als der 6502 ist und nicht mit 10GHz läuft.
Nach Moore und so wäre nämlich ein drastisch höherer Performancezuwachs zu erwarten. Aber man hat ihn im wesentlichen nur genutzt um Speicher auf den Chip zu packen.
Ich verstehe nicht warum die dicken CPU von Intel & AMD mit 3+ GHz laufen, die kleinen RISC aber nicht mindestens ebenso. Ja, man braucht eine Spannungsregelung ja, die I/O Pins brauchen grosse und langsamen Transistoren, aber den Kern könnte man trotzdem mit GHz laufen lassen, PLL wurden auch schon erfunden.
ASCII-String dauert IMHO mindestens 13,5 Zyklen/Ziffer, u.a. deswegen,
weil dem 6502 ein Nibble-Swap-Befehl fehlt. In Summe sind das – bei
vollständig ausgerollten Schleifen 18 Zyklen/Ziffer. Selbst bei gleicher
Ich verstehe nicht warum die dicken CPU von Intel & AMD mit 3+ GHz
Die ziehen aber auch 100A und nicht 10mA ...
Die Hauptlimitierung bei MCUs ist übrigens der Speicher. Flash ist generall langsam und auch das SRAM ist normalerweise nicht auf Geschwindigkeit optimiert.
Man kann allerdings durch gezieltes Prompting ein geeignetes Programm
erzeugen
Unser Geschäftsführer träumt schon davon, das wir für unsere Online-Dienste bald keine individuellen Frontends mehr brauchen, weil die Benutzer einfach einen Prompt verfassen. Nach dem Motto: "Ich möchte ab morgen in den Tarif XL wechseln und dabei das Angebot für die neue Transportkiste wahrnehmen".
Na ja, peinlich ist eher, dass der AVR obwohl 40 Jahre jünger nur etwas
schneller als der 6502 ist und nicht mit 10GHz läuft.
Der AVR kann mindestens 16x so schnell getaktet werden. Wenn das nicht erheblich schneller ist, was dann?
Außerdem enthält er eine Menge integrierte Peripherie, für die man früher extra Geld und Platz brauchte. Sogar den Flash-Speicher, EEprom und einen Debugger-Interface. Davon durfte man zu 6502 Zeiten nicht mal träumen.
Sogar den Flash-Speicher, EEprom
und einen Debugger-Interface. Davon durfte man zu 6502 Zeiten nicht mal
träumen.
Externer EPROM und Logic-Analyzer am Bus hatte aber auch so seine Vorteile, speziell wenn der Chip nicht mehr will und man den Speicher kopieren will/muss.
Externer EPROM und Logic-Analyzer am Bus hatte aber auch so seine
Vorteile, speziell wenn der Chip nicht mehr will und man den Speicher
kopieren will/muss.
Es war ein notwendiges Übel, weil man die Hardware debuggen musste! Will heute keiner mehr haben, denn man bekommt astrein getestete Hardware!
Hier die Variante in C64 Basic, deutlich schneller als gedacht. Die Berechnung dauert ca. 2s, die Ausgabe incl. Scrolling 1s. D.h. die 384 Zahlen sind in ca. 1152s ~ 19min ausgegeben. Not too bad.
Kann ein fünfzig Jahre alter Mikroprozessor (der originale MOS6502
ca.1976) schneller arbeiten als ein deutlich modernerer AVR ATmega32u4
(oder ähnlicher Typ)?
Alter schützt vor speed nicht.
Auch ein "Trabi" kann schneller sein als ein "Tesla" ...
im freien Fall. ;-)
Es war ein notwendiges Übel, weil man die Hardware debuggen musste! Will
heute keiner mehr haben, denn man bekommt astrein getestete Hardware!
So toll getestete Hardware wie der STM32 in so einem Laser-Entfernungsmesser von mir, der wahrscheinlich mal Brown-Out oder sonstwas hatte und sich dann wahrscheinlich Müll ins Flash geschrieben hat.
Bei Kram aus den 1980/1990ern einfach EPROM kopieren, bei dem Scheiss von heute wegwerfen oder warten, dass mal einer Firmware leakt.
Auch ein "Trabi" kann schneller sein als ein "Tesla" ...
im freien Fall. ;-)
Aber nur wenn man den Trabi mit Beton füllt.
Nö. Im freien Fall in Luft nimmt der Trabi von allein eine (bezüglich des Luftwiderstands recht günstige) und ziemlich stabile aerodynamische Lage ein.
Der Tesla hingegen tut das nicht, der bewegt sich völlig chaotisch. Liegt an der Masseverteilung mit Schwerpunkt nahe an der größten Fläche, aber nicht in deren Mitte.
Die Energie, die die turbulente Bewegung schluckt und die hohe Wahrscheinlichkeit für ungünstige Luftwiderstände im chaotischen Fallverlauf mindern die terminal velocity des Tesla deutlich gegenüber dem Trabi in stabiler Fluglage.
Zumindest diesbezüglich gewinnt eindeutig der Trabi.
Der Einschlagkrater fällt allerdings trotz der deutlich höheren Einschlaggeschwindigkeit erheblich kleiner aus als der des Tesla. Masse läßt sich halt nur schwer ersetzen.
Hier noch eine Implementation in Basic für den Apple. Sie läuft inkl.
Bildschirmausgabe in 4,5 Minuten durch. Damit das Video nicht so lange
dauert, habe ich in der Mitte ein Stück herausgeschnitten.
Beachtlich! Deutlich schneller als meine C64 Variante, obwohl es die gleiche CPU ist. Ok, netter Trick, vier Dezimalstellen in einer Zahl zu verarbeiten ;-)
ChatGPT ist optimal zum Erzeugen von Politikerreden!
Es gibt eigentlich nur eine Sache, die KI richtig gut kann: Menschen täuschen. Da passen, neben Phishing-Mails und Deep-Fakes, auch Politikerreden mit rein.
Hier noch eine Implementation in Basic für den Apple. Sie läuft inkl.
Bildschirmausgabe in 4,5 Minuten durch.
Ich hab deine Variante mal im VICE laufen lassen. 6:40 ist schon mehr als doppelt so schnell wie mein Original, aber immer noch etwas langsamer als der Apple ][. Vor allem muss man den Unfug von Basic 2.0 umschiffen, bei welchem bei STR$() immer ein führendes Leerzeichen für positive Zahlen erzeugt wird!
Du sparst ja am Anfang auch viele Iterationen ein, wenn kein Carry mehr vorhanden ist. Das ist glaube ich der wesentliche Zeitgewinn, denn am Ende ist die Berechnung fast genau so langsam, egal ob mit einer oder 4 Dezimalstellen / Arrayzelle.
Beachtlich! Deutlich schneller als meine C64 Variante, obwohl es die
gleiche CPU ist. Ok, netter Trick, vier Dezimalstellen in einer Zahl zu
verarbeiten ;-)
Eigentlich ist es ja Blödsinn, nur vier Dezimalstellen am Stück zu
verarbeiten. Ich habe das deswegen gemacht, weil die Integerveriablen
(mit '%'-Suffix) in Applesoft-basic 16 Bit breit sind, so dass die Summe
9999+9999=19998 noch gut hineinpasst. Dann habe ich aber herausgefunden,
dass das Programm mit den Integervariablen langsamer ist als mit Float.
Offensichtlich rechnet der Interpreter intern ausschließlich in Float
und muss deswegen die Integervariablen erst dorthin konvertieren, was
zusätzliche Zeit kostet.
Wenn aber sowieso in Float gerechnet wird, können deutlich mehr als nur
vier Stellen am Stück verarbeitet werden. Applesoft-Basic verwendet
40-Bit-Floats (1 Bit Vorzeichen, 31 Bits Mantisse und 8 Bits Exponent).
Mit den 31 Bits der Mantisse lassen sich Integerzahlen bis 2**32-1 ≈
4.3E9 lückenlos darstellen.
Somit kann man bspw. die gewünschten 80 Stellen in 10 Päckchen à 8
Stellen aufteilen. Das Programm braucht dann nur noch 2m49.
Oder man erhöht die Gesamtstellenzahl auf 81 und teilt diese in 9 mal 9
Stellen auf. Damit werden alle Fibinacci-Zahlen mit maximal 81 Stellen
in 2m42 berechnet. Die größte 80-stellige Zahl wird nach 2m38 angezeigt.
Gegenüber den 2m49 von oben ist die Verbesserung eher gering, was aber
evtl. darauf zurückzuführen ist, dass die 81-stelligen Zahlen jeweils 3
statt 2 Zeilen auf dem Bildschirm beanspruchen, was mehr Scrollaufwand
bedeutet.
Coole Sache, das! Vor allem auch die Tatsache, dass er in Apples, CBMs
und etlichen Schachcomputern die reguläre CPU ersetzen kann. Das sollte
man vielleicht wirklich mal nachbauen.
Vielleicht arbeitet Jürgen Müller (der Entwickler) ja bereits an einem
AVR mit 1,6 GHz :)
Hier die Variante in C64 Basic, deutlich schneller als gedacht.
lach... danke dafür. In der Tat deutlich schneller als ich dachte. So schlecht wie man das heute manchmal in Erinnerung hat, war der alte Kasten eben doch nicht.
Der Einschlagkrater fällt allerdings trotz der deutlich höheren
Einschlaggeschwindigkeit erheblich kleiner aus als der des Tesla. Masse
läßt sich halt nur schwer ersetzen.
Masse geht linear in die kinetische Energie, Geschwindigkeit dagegen quadratisch in die kinetische Energie.
; Stoppe nach 12 Fibonacci-Zahlen (Du kannst das anpassen)
BEQ done ; Wenn 12 Fibonacci-Zahlen erreicht, Ende
Nicht 12.
Der Ersteller dieses Programms hat nicht mal im Ansatz verstanden, dass es um die Behandlung sehr großer Zahlen geht, die eben nicht mehr in ein einziges Byte hineinpassen. Das lässt sich auch nicht mal eben so hochskalieren.
Und warum formuliert der Ersteller des Postings dann nicht gleich, was
er sagen will?
Er wollte wohl den Beweis seiner Aussage gleich mitliefern. Stattdessen hat er exakt das Gegenteil erreicht, er hat seine beabsichtigte Aussage gleich selbst widerlegt. Grandios!
Er wollte wohl den Beweis seiner Aussage gleich mitliefern. Stattdessen
hat er exakt das Gegenteil erreicht, er hat seine beabsichtigte Aussage
gleich selbst widerlegt. Grandios!
die kleinen RISC aber nicht mindestens ebenso. Ja, man braucht
eine Spannungsregelung ja, die I/O Pins brauchen grosse und langsamen
Transistoren, aber den Kern könnte man trotzdem mit GHz laufen lassen,
PLL wurden auch schon erfunden.
Du beschreibst STM32N6? (ok, GHz nur fast, aber nahe dran).
Dreistellige MHz sind ab Cortex M4 ("G4xx") im µC-Bereich schon lange Standard, PLL noch viel länger.
Aber "die kleinen RISC": haben andere Optimierungsziele.
Der Arduino Nano 6502 Emulator läuft etwa 5 mal langsamer als ein Apple 2 und braucht 0.79s.
Deshalb sollte ein mit 1Mhz getaktete 6502 die 80 Digit Fibonacci-Rechnung in ca. 160ms schaffen.
Jetzt bleibt die Frage: Wie schlägt sich der mit 16MHz getaktete Atmega im Vergleich?
Ben B. (Firma: Funkenflug Industries) (stromkraft)
Andere Frage: Gibt es überhaupt irgendwas, wo ein 6502 im Vergleich zu
einem (evtl. gleich getakteten) ATMega schneller ist?
Also die Eingangaussage war ja, dass es ein Programm gibt, welches auf einem 1Mhz 6502 schneller als auf einem 16MHz Atmega läuft.
Mein Assemblerprogramm sollte das einem realen 6502 in 160ms schaffen. Jetzt ist zu zeigen, dass ein 16MHz Atmega das schneller kann.
Das Problem wir vermutlich unterschätzt.
Norbert schrieb
Kann ein fünfzig Jahre alter Mikroprozessor (der originale MOS6502
ca.1976) schneller arbeiten als ein deutlich modernerer AVR ATmega32u4
(oder ähnlicher Typ)? Der wurde irgendwann ab 2008 released.
Der AVR darf mit 16 MHz getaktet werden, der MOS6502 kann nur 1 MHz.
ich bin der Meinung, dass es einen absoluten Gleichstand gibt, wenn man C++ Template Programmierung anwendet. Warum? Weil zur Laufzeit nur noch die zur Compilezeit berechneten Werte ausgegeben werden müssen. Ob nun 32Bit oder 80Bit würde nichts am Gleichstand ändern.
ich bin der Meinung, dass es einen absoluten Gleichstand gibt
Das man das Ganze mit C++ macht, ist eine interessante Idee.
Wenn man das 80 stellige Ergebnis der Fibonacci Folge in eine Binärzahl kodieren will, braucht man 266 Bits. Bist du sicher, dass deine Implementierung das kann?
Es wäre super, eine Laufzeitmessung in das Programm einzufügen:
start=micros();
und
t=micros()-start;
dann kann gleich sehen, ob das ganze funktioniert.
Eigentlich geht es doch nur darum, welcher µP/µC schneller Berechnungen durchführt. Dehalb ist die Ausgabe jeder einzelnen Zahl doch eigentlich überflüssig und könnte auf ein Fertig-Flag reduziert werden.
Dehalb ist die Ausgabe jeder einzelnen Zahl doch eigentlich
überflüssig und könnte auf ein Fertig-Flag reduziert werden.
Da hast du Recht. Ich habe in den 6502 Simulator einen Zyklenzähler eingebaut und die Zeit mal berechnen lassen:
Mit Ausgabe der Zahl
6502 simulator output:
79757008057644623350300078764807923712509139103039448418553259155159833079730688
cpu cycles used 148565
6502 cpu clock 1000000
calculation time 0.148565
Ohne Ausgabe der Zahl
6502 simulator output:
cpu cycles used 145561
6502 cpu clock 1000000
calculation time 0.145561
Hier mal die Arduino-Variante. Dauert 2777ms mit Ausgabe auf UART mit
115200 Baud. Ohne UART-Ausgabgbe 72ms! Das wird eng für den 6502! ;-)
Oh, das habe ich doch glatt überlesen .. Da wird es tatsächlich etwas eng für den 6502 (145ms bisher) ..
Ich meine, man kann da noch etwas raus quetschen.
edit:
Bei deiner Berechnung dürften noch 2 Iterationen fehlen.
Die maximale Zahl Fibonacci-Zahl in 80 Digits ist
https://sbc.rictor.org/avr65c02.html
Der ATMega1284P bei 24mhz CLK schafft wirst case 1,9MHz 6502 code
emulation... Also sollte das am 32u4 bei 16mhz immer noch mit 1,3MHz
laufen (IIRC, sind das die selben cores).
Damit wird zumindest der Vergleich mit dem 1MHz 6502 schon ziemlich
absurd.
[Edit]
Ein weiterer Emulator: https://2m5.de/6502_Emu/index.htm
Der schafft anscheinend am mega16 mit 16MHz einen 2mhz 6502 clock
[/Edit]
cpu cycles used 145561
6502 cpu clock 1000000
calculation time 0.145561
Apropos: Ich glaube, der Atmega hat gewonnen. Die Version von Falk schafft schon 72ms (ohne Optimierung). Mein Version für den 6502 könnte man noch etwas optimieren, aber es wird sehr knapp auf weniger als die halbe Ausführungszeit zu kommen. Die Bearbeitungszeit auf dem 6502 für 1 Byte ( 2 Digits ) braucht 9 Zyklen.
Dehalb ist die Ausgabe jeder einzelnen Zahl doch eigentlich
überflüssig und könnte auf ein Fertig-Flag reduziert werden.
Da hast du Recht. Ich habe in den 6502 Simulator einen Zyklenzähler
eingebaut und die Zeit mal berechnen lassen:
Mit Ausgabe der Zahl
6502 simulator output:
797570080576446233503000787648079237125091391030394484185532591551598330
79730688
cpu cycles used 148565
6502 cpu clock 1000000
calculation time 0.148565
Das wären aber verdammt wenige Takte. Ein AVR mit 1 MHz wäre langsamer, denn der braucht nach der aktuellen Versionen 72ms bzw. 15ms bei 16 MHz. Macht 1152ms bzw. 240ms bei 1MHz. Kann ich nicht so recht glauben. Zeig das vollständige Programm.
Hier ist es (damit die Ki's auch noch was lernen können).
Ok, Die Schleife zum Addieren entrollt, braucht 9 Takte / Dezimalstelle.
Der AVR könnte das mit
1
ld r16, x+ ; 2
2
ld r17, y ; 2
3
adc r16, r17 ; 1
4
st y+, r17 ; 2
in 7 Takten, hat aber keinen BCD Modus. Also muss man das nachbilden, was wieder einige Takte kostet, auf jeden Fall mehr als 2! Und damit ist der 6502 erstaunlicherweise bei gleichem Takt schneller als der AVR! Uuuups!
Aber trotzdem ist man damit meilenweit von der ursprünglichen Behauptung des OPs weg.
"Kann ein fünfzig Jahre alter Mikroprozessor (der originale MOS6502
ca.1976) schneller arbeiten als ein deutlich modernerer AVR ATmega32u4
(oder ähnlicher Typ)? Der wurde irgendwann ab 2008 released.
Der AVR darf mit 16 MHz getaktet werden, der MOS6502 kann nur 1 MHz."
Nein, kann er nicht mal ansatzweise, auch wenn er bei gleichem Takt geringfügig schneller ist.
Hier kann man das 6502 Programm in einem Online Emulator laufen lassen.
Blöd ist nur, daß man den Taktzähler nur zurücksetzen kann, wenn man die Seite komplett neu lädt.
In der realen Welt, der realen Schaltungen, abseits des akademischen Brainfucks dieses Threads, ist nicht die reine Taktrate, oder MIPS Rate entscheidend sondern die Peripherie macht den Unterschied. Und da sieht ein 6502 halt erst so richtig alt aus. Dass der arschlahm ist, kommt lediglich als weitere Einschränkung dazu.
Ok, es sind 9 Takte / 2 Dezimalstellen. Es sind ja 2 BCD Zahlen / Byte. Ist aber egal, denn auch die AVR-Variante kann man problemlos und ohne Zusatzaufwand dahin trimmen. Der Vergleich ist dann halt mit 100 statt 10.
Ein Video des Programmlaufes auf dem Commodore ist bereits erstellt,
allerdings ist das mp4 um die 10MB groß.
Das werde ich später einstellen.
Dazu ebenfalls eine »fibonacci.p00« Datei.
Damit kann es jeder selbst laufen lassen und überprüfen. (Läuft auch auf
dem VICE)
Und natürlich die korrekten Ergebnisse mit der Ausgabe des Python
Programms verifizieren.
Dein Code entspricht nicht ganz Norberts Vorgaben. Du darfst zwar für
die Zeitmessung die Bildschirmausgabe weglassen, nicht aber die
Umwandlung nach ASCII. Zudem muss diese Umwandlung für /jede/ der 382
Zahlen erfolgen, nicht nur für die letzte. S. hier:
Wir hatten das damals so vereinbart, das die auszugebenden Daten einzeln
Zeilenweise als fertiger String im Speicher bereit liegen müssen.
Um sicher zu gehen, dass Norbert mit "String" nicht ein eine Folge
gepackter BCD-Bytes meint (was für den 6502 natürlich vorteilhaft wäre),
habe ich extra noch einmal nachgefragt:
Mit "String" meist du einen ASCII-String (also eine Folge von Bytes in
0x30..0x39), der (bei aktivierter Ausgabe) ohne weitere Konvertierung in
den Bildspeicher kopiert werden kann?
Ganz genau so!
Da die Umwandlung nach ASCII deutlich länger dauert als die Berechnung,
kann der 6502 den Vorteil seiner hardwaremäßigen BCD-Addition kaum
ausspielen. S. auch hier:
Die BCD-Addition geht zwar superschnell (4,5 Taktzyklen pro Ziffer inkl.
Laden und Speichern), aber die anschließende Umwandlung in einen
ASCII-String dauert IMHO mindestens 13,5 Zyklen/Ziffer, u.a. deswegen,
weil dem 6502 ein Nibble-Swap-Befehl fehlt. In Summe sind das – bei
vollständig ausgerollten Schleifen 18 Zyklen/Ziffer. Selbst bei gleicher
Taktfrequenz dürfte der 6502 trotz des BCD-Modus das Rennen immer noch
knapp verlieren. Das liegt u.a. auch daran, dass er etwa doppelt so
viele Zyklen pro Instruktion braucht als der AVR.
Hätte Norbert in der Aufgabe gefordert, dass die Fibonacci-Zahlen in
gepacktem BCD (statt in ASCII) abgelegt werden, stünde der 6502 sehr
viel besser da.
In der realen Welt, der realen Schaltungen, abseits des akademischen
Brainfucks dieses Threads, ist nicht die reine Taktrate, oder MIPS Rate
entscheidend sondern die Peripherie macht den Unterschied.
Wenn man so eklatante Fehler macht, den Unterschied zwischen einem Mikroprozessor und einem Mikrocontroller zu unterschlagen, dann ...
Dein Code entspricht nicht ganz Norberts Vorgaben. Du darfst zwar für
die Zeitmessung die Bildschirmausgabe weglassen, nicht aber die
Umwandlung nach ASCII. Zudem muss diese Umwandlung für jede der 382
Zahlen erfolgen, nicht nur für die letzte. S. hier:
Tja, könnte man machen, die Frage ist, ob man noch was neues lernt.
Was man aus diesem Thread mitnehmen kann, dass Spezialbefehle bestimmt Rechnungen enorm beschleunigen können. So ist der AVR gegenüber dem 6502 bei gleich Taktfrequenz bei der Addition großer BCD Zahlen deutlich schneller.
Und um den Bogen in die Neuzeit zu bekommen:
Auf der Embedded gab es am Espressif-Stand einen kleinen Zweiradroboter mit ESP32 der auf Sprachbefehle reagiert hat. Es handelte sich um einen der neueren ESP32 mit eingebautem KI-Beschleuniger ( welchen, weiß ich nicht mehr, aber vielleicht kann da jemand helfen ).
Meine Nachfrage, ob da eine NPU eingebaut ist, wurde verneint: Es würde sich um eine reine Befehlserweiterung handeln und diese würde dies KI-Rechenleistung ermöglichen. Leider gab es sonst keine weiteren Informationen.
Das ist grundsätzlich spannend und ich bin gespannt, ob der nächste PiPico nach dem PiPico 2 einen RiscV mit angeflanschtem KI-Befehl bekommt.
Was man aus diesem Thread mitnehmen kann, dass Spezialbefehle bestimmt
Rechnungen enorm beschleunigen können.
Das konnte man auch bei den DSPs lernen die einen MAC (multiply add) Befehl haben und deshalb in der Signalverarbeitung ihre Nase vorne haben. Dass es einen Unterschied geben muss, sollte schon aus der Tatsache heraus, dass es Spezialbefehle gibt, zu erahnen sein.
Der Thread veranschaulicht ganz gut wie deutlich der Unterschied wird. Das finde ich beeindruckend wie dieses simple Beispiel zeigt.
Und mal ehrlich, wer hätte damit gerechnet. Norbert vermutlich ;)
Tja, könnte man machen, die Frage ist, ob man noch was neues lernt.
In der Tat.
Was man aus diesem Thread mitnehmen kann, dass Spezialbefehle bestimmt
Rechnungen enorm beschleunigen können.
Wo denn? Ich nehme gerade das GEGENTEIL mit! Die BCD Arithmetik des 6502 ist nur geringfügig schneller, wenn es um die reine Addition geht. Sobald es um die wettbewerbsgemäße Umwandlung in ASCII geht, ist der Vorteil dahin.
So ist der AVR gegenüber dem 6502
bei gleich Taktfrequenz bei der Addition großer BCD Zahlen deutlich
schneller.
Nö. Die reine Addition ist auf dem 6502 geringfügig schneller bei entrollten Schleifen. Die anschließende Umwandlung in ASCII frißt den Vorsprung wieder auf und der 6502 liegt dann wieder einigermaßen hinten (bei gleichem Takt).
Soviel zum Thema "Lernen". Aber da du ein Freund von KI bis, bist du damit vermutlich besser beraten als mit NI ;-)
Nö. Die reine Addition ist auf dem 6502 geringfügig schneller bei
entrollten Schleifen. Die anschließende Umwandlung in ASCII frißt den
Vorsprung wieder auf und der 6502 liegt dann wieder einigermaßen hinten
(bei gleichem Takt).
Dafür spart man die Division bei der Konvertierung in ASCII-Zahlen.
Dafür spart man die Division bei der Konvertierung in ASCII-Zahlen.
Das war gar nicht das Thema, sondern daß auf Grund des Mangels anderer Befehle (Nibble Swap) und mehr Takte/Befehl der 6502 bei gleichem Takt die BCD Zahlen nur langsamer in ASCII wandeln kann als der AVR.
Dafür spart man die Division bei der Konvertierung in ASCII-Zahlen.
Das war gar nicht das Thema, sondern daß auf Grund des Mangels anderer
Befehle (Nibble Swap) und mehr Takte/Befehl der 6502 bei gleichem Takt
die BCD Zahlen nur langsamer in ASCII wandeln kann als der AVR.
Lookup-Table könnte man testen bzw. überdenken.
Allerdings könnte der indirekte Zugriff über das RAM und der nur 8-Bit große Index einen Strich durch die Rechnung machen.
Die BCD Arithmetik des 6502 ist nur geringfügig schneller, wenn es um
die reine Addition geht. Sobald es um die wettbewerbsgemäße Umwandlung
in ASCII geht, ist der Vorteil dahin.
Hier im Wettbewerb ist der Vorteil dahin durch die Ausgabe. Trotzdem finde ich es beeindruckend, was ein einzelner "Spezialbefehle" für Geschwindigkeitsvorteile hier im behandeln von BCD bringt. So wie auch die MAC Befehle (auf anderem Gebiet) in einem DSP.
Ich würde mich da jetzt nicht auf die Geschwindigkeit der Anzeige versteifen. Die ist bei vielen Rechnungen uninteressant, denn man kann ja viele Rechenschritte kombinieren und dann das Ergebnis anzeigen.
Ich erlaube mir hier mal der KI eine Frage zu stellen:
"Wo wird heute noch das BCD-Zahlenformat eingesetzt"
Das BCD-Zahlenformat wird heute noch eingesetzt:
Im Finanzwesen für exakte Geldbetragsdarstellung,
In der Wissenschaft für deterministische, dezimalgenaue Berechnungen,
In Steuerungssystemen und Maschinensteuerungen,
Bei der Zeitcodierung (z. B. DCF77),
Bei speziellen Kommunikationsformaten (z. B. SMS-PDU)
Trotz seiner Speicherineffizienz bleibt BCD in diesen Nischenanwendungen relevant, wo Genauigkeit und einfache Umwandlung zwischen Mensch und Maschine wichtiger sind als Speichereffizienz.
Da stehen auch lustige Sachen drin, die nicht mehr so richtig aktuell sind:
"Diese ist z. B. bei 32-bit oder 64-bit Gleitkommazahlen auf einer weit verbreiteten Prozessorplatform nicht gegeben (80 Bit Rechenregister, 32/64 Bit Speicher)."
Da stehen auch lustige Sachen drin, die nicht mehr so richtig aktuell
sind:
Auch solche.
"Allerdings wird sie überwiegend im Finanzwesen aus Tradition und auch aus Unwissenheit heraus weiter verwendet. "
"Ein 64-bit Register vermag das Zehnfache des gesamten Weltvermögens in Tausendstel-Auflösung darzustellen, Überläufe sind spätestens bei einer 128-Bit Zahl nicht mehr realistisch."
Hehe ;-)
"Auch in Teilen der Wissenschaft wird gelegentlich noch BCD verwendet, wenn die Korrektheit aller Dezimalstellen oder eine strikt deterministische Berechnung (die gleichen Operationen mit der gleichen Eingabe erzeugen stets die gleiche Ausgabe) benötigt wird. "
Unfug. Das geht auch mit Integer! Und auch Fließkomma sind deterministisch! Da ist kein Zufallsgenerator drin! Die meinen bestenfalls Rundungsrauschen.
"Die fehlenden Rundungsfehler der Darstellung von Dezimalzahlen kann man durch Gleitkommazahlen mit Basis-10-Exponent oder durch Festkommazahlen mit Basis-10-Exponent genauso erreichen. "
Bissel aufgeräumt und den UART vollständig konfiguriert. Ist für ATmega 328P mit 80 Stellen compiliert, aka Arduino Uno/Micro/Nano. Hexfile liegt im Archiv. Ausgabe über UART mit 76800 Baud. Und falls einer die Fibonaccizahlen mit 200 Stellen braucht, siehe Anhang. ;-)
"Auch in Teilen der Wissenschaft wird gelegentlich noch BCD verwendet,
wenn die Korrektheit aller Dezimalstellen oder eine strikt
deterministische Berechnung (die gleichen Operationen mit der gleichen
Eingabe erzeugen stets die gleiche Ausgabe) benötigt wird. "
Unfug. Das geht auch mit Integer! Und auch Fließkomma sind
deterministisch! Da ist kein Zufallsgenerator drin! Die meinen
bestenfalls Rundungsrauschen.
Vorsicht, andere Compiler-Flags oder andere Optimierungs-Level könnten möglicherweise unterschiedliche Rundungsfehler nach sich ziehen, weil z.b. Teilterme rausgezogen werden oder in anderer Reihenfolge gerechnet wird.
Daher würde ich das erstmal nicht so unterschreiben.
Das ist eine 1 mit 100 Nullen. Also ist die größe 200 stellige Fibonaccizahl knapp unter googol^2, also eine 1 mit 200 Nullen. Es gibt ne Schätzung, daß es "nur" ca. 10^80 Atome in bekannten Universum geben soll. (Die Rechnung würde mich mal interessieren)
Und weil ich gerade dabei bin, hier die C64 Version in Assembler.
Die Berechnung und Ausgabe braucht $22 Ticks vom Systemtimer (60Hz!), macht 566ms. Es werden pro Bildschirm 6 Zahlen angezeigt. D.h. die 382 berechneten Zahlen FIB(3)-FIB(384) brauchen 64 Bildschirme zur Anzeige, was bei 50Hz PAL 1,28s dauert. Sprich, die Berechnung im Videoram ist schneller als die Anzeige ;-)
Siehe Anhang, Quelltext und PRG zum selber ausprobieren auf dem Emulator (VICE) oder echter Hardware.
Ach so. Es ist natürlich auch der Trick von Yalu drin, welcher die Anzahl der zu addierenden Stellen schrittweise erhöht, wenn es einen Überlauf gibt. Damit spart man im Mittel die Hälfte aller Additionen und die Rechnung ist quasi doppelt so schnell.