Hello, Guest the thread was called101k times and contains 1748 replays

last post from Hoogo at the

Neuer Retro-Computer im 8-Bit Style

  • Wichtig: Im Unterschied zum END von Oberon (oder auch dem Semikolon bei C) ist das NEXT in Basic nicht das syntaktische Kennzeichen für das Ende der FOR-Schleife, sondern eine eigenständige. konkrete Anweisung für sich: Suche im Stapel nach einer Sprungadresse, die mit der Variablen I verknüpft ist und springe dahin. Dieses Verhalten ist aber laufzeitabhängig und kann daher nicht vom Compiler in ein paar (Prozessor-)Befehle übersetzt werden. In Pascal, C, Python usw. ist dies jerdoch möglich, da dort jede Schleife ein genau definiertes Ende hat, und END keine Anweisung ist.

    Auch QB haut dir das um die Ohren, das waren nur die primitiven Zeilennummerinterpreter die dir das durchgehen haben lassen.

  • Ich programmiere auch gern im DIV DX (damals DIV Games Studio für MSDOS) für Windows und finde prozedure Programmierung irgendwie besseer als objektorientierte Programmierung. Hier mal ein (sorry, etwas längeres) Tutorial von mir, wie man ein tile-basiertes Jump & Run Spiel im Stil von M*rio programmiert. Grafiken für Sprites usw. werden da aber nachgeladen.


    Ansonsten würde ich mir einfach das BASIC vom 128er mit einer viel höheren Geschwindigkeit wünschen, um Actionspiele programmieren zu können.

  • Die Beschleunigung von BOSS-Kompilaten im Vergleich zum interpretierten BASIC soll ("nicht selten") bis zu 100-fach sein, das käme von der Größenordnung in die Nähe von handgeschriebenem Assembler (100-1000-fach).

    Der C64 ist einfach zu langsam. Für gute Sachen kommst nicht an Assembler vorbei.

    Also ich hab grad mal ein BASIC-Spiel von mir mit BasicBOSS kompiliert, und komme auf ca. doppelte Ausfuehrgeschwindigkeit.

    "Die Beschleunigung von BOSS-Kompilaten im Vergleich zum interpretierten BASIC soll [!] ("nicht selten") [wie selten?] bis zu 100-fach sein [...]"


    Solche Aussagen von Compilerherstellern würde ich immer mit Vorsicht genießen und selbst austesten. Streng genommen ist auch ein Faktor 0.5 im Bereich "bis zu 100".

    Derselbe Quellcode oder an BOSS angepaßt?

    Nee ohne Anpassungen

    Also ich habe nun mal Basic-Boss an meinem obigen Programm getestet, erst ohne, dann mit Anpassungen:


    Zunächst ohne Anpassungen, das erbrachte eine Beschleunigung der zeitkritischen Stelle (Unterprogramm zur Umwandlung der Strings in Sprite-Daten) von 942 Jiffys (Sechzigstelsekunden) = 15,7 Sekunden auf 291 Jiffys, also um den Faktor 3,19. Die Dauer der Sprite-Bewegung am Programmende verkürzt sich von 186 auf 24 Jiffys, da ist der Beschleunigungsfaktor 7,75.


    Dann schaltete ich in einer REM-Zeile mit Compiler-Direktiven auf schlankere Datentypen. Damit brauchte das Unterprogramm noch 77 Jiffys, also etwas über 1 Sekunde, das bedeutet eine Beschleunigung um den Faktor 12,23. Die Sprite-Bewegung verkürzt sich auf 1 Jiffy, ist also nicht mehr wahrnehmbar - der Beschleunigungsfaktor ist 186.


    Dann fügte ich die Direktive FASTFOR für optimierte Schleifen hinzu, das verkürzte das Unterprogramm auf 69 Jiffys, Faktor 13,65. Bei der Sprite-Bewegung steht der Jiffy-Zähler wieder auf 1.


    Um noch aussagekräftig messen zu können, habe ich dann im Code die Sprite-Bewegung verlängert, so dass X- und Y-Koordinate kleinteilig in 1er-Schritten von 0 bis 255 (also über den Bildschirmrand hinaus) laufen; dies dauert unkompiliert 540 Jiffys. Kompiliert mit schlanken Datentypen und FASTFOR: 2 Jiffys, also 270-fache Geschwindigkeit.


    Weitere Versuche mit Optimierungs-Maßnahmen (z. B. Deklarierung von FAST-Variablen, die in der Zeropage abgelegt werden), brachte für das Unterprogramm höchstens noch 1-2 Jiffys - ich denke, bei diesem Unterprogramm ist der Flaschenhals die String-Verarbeitung, die der Compiler nur begrenzt beschleunigen kann.


    Also mit wenigen Direktiven in einer REM-Zeile wurde der Beschleunigungsfaktor für das stringlastige Unterprogramm zweistellig (13,65), für die Sprite-Bewegung dreistellig (270).


    Der aus beiden Abschnitten gebildete Durchschnitt ist 141,83.


    Nach Durcharbeitung des gesamten Handbuchs ist mit ausgefeilteren Optimierungen vielleicht noch mehr drin.


    unkompiliert.prg

    kompiliert.prg

  • BASIC lebt ;-)

    heise.de/news/PicoMite-Neuer-Basic-Interpreter-fuer-den-Raspberry-Pico


    Ich hab vor Jahren einen Duinomite gekauft mit MMBasic und fand es ganz brauchbar. Bei einem 80 MHz PIC32 auf jeden Fall sehr schnell.

    Allerdings ist MMBasic nicht wirklich Open Source, man kann ihn nur für persönliche Zwecke beim Autor anfragen (hatte ich getan und hab ihn auch bekommen).

    Nun ist angekündigt, dass die PicoMite Version unter eine "BSD ähnliche" Lizenz gestellt werden soll.

    Ein Port auf Raspi (Zero bis 400) - möglichst bare-metal - fände ich wirklich interessant.

  • Man kann Abstand nehmen von der Vorstellung, ein Compiler auf einem Retrorechner könnte so gut sein wie der gcc. Es wird halt Code erzeugt, aber eben nicht so schön optimiert wie auf dem PC. Das wäre vielleicht keine große Hürde. Immerhin besteht ja weiterhin die Option, den gleichen Text auf dem PC auch mit einem größeren Compiler zu übersetzen, sofern man denn will.

    Wenn man folglich bereit ist, Abstriche in der Codequalität zu machen, kann man auch einen kleineren Compiler nehmen. Der würde dann nicht Zwischencode für das gesamte Programm benutzen, sondern nur lokal arbeiten, d. h. das ganze Programm in Subroutinen aufspalten und diese Stück für Stück übersetzen.

    So wie ich das verstanden habe, entspricht das auch dem gängigen Release/Debug-Modell, oder?


    Also ein schneller, nativer Compiler, der zwar wenigoptimierten, dafür aber beim (lokalen) Debuggen nachvollziehbaren Code erzeugt. Und ein Cross Compiler, der unter Ausnutzung heutiger Rechnerressourcen hochoptimierte Programme (Releases) erstellen kann.

  • So wie ich das verstanden habe, entspricht das auch dem gängigen Release/Debug-Modell, oder?


    Also ein schneller, nativer Compiler, der zwar wenigoptimierten, dafür aber beim (lokalen) Debuggen nachvollziehbaren Code erzeugt. Und ein Cross Compiler, der unter Ausnutzung heutiger Rechnerressourcen hochoptimierte Programme (Releases) erstellen kann.

    Ja, natürlich. Dieses Konzept existiert auch bereits für den C64. Wer unbedingt in Basic programmieren will. kann dies auf dem C64 (oder besser mit dem C64Studio) ja tun. Am Ende aber empfiehlt es sich, den Code durch den Compiler von EgonOlsen71 zu jagen, der das beste Kompilat erzeugt. Man könnte daher auch sagen, daß die Diskussion über Basic-Compiler auf dem C64 sich damit längst erledigt hat - und auch nicht in diesen Thread gehört.


    Der Nachteil eines Interpreters wie in Basic ist jedoch, daß der Abstand zum Kompilat sehr groß ist. Möchte man ein Programm schreiben, das auf Geschwindigkeit angewiesen ist, kann man aufgrund der Differenz in der Geschwindigkeit zwischen Interpreterausführung und Kompilat keine Rückschlüsse ziehen auf das Endergebnis. Auch das Speicherverhalten hinsichtlich Codegröße und Speicherbelegung der Variablen ist sehr unterschiedlich. Verwendet man jedoch von Anfang an einen Compiler, minimiert dies den Abstand drastisch. Sicherlich kann ein Compiler auf dem PC den Code stark optimieren, aber mehr als die doppelte Geschwindigkeit (eine sehr optimistische Schätzung) dürfte auch der beste Compiler nicht herausholen können.


    Ein Compiler für eine Hochsprache, die einigermaßen komfortabel ist (wie z. B. Pascal), benötigt für seine Kompilierung jedoch auch eine geeignete Zielmaschine, d. h. der Prozessor sollte nach Möglichkeit typische Elemente einer Hochsprache wie z. B. 16 Bit-Zahlwerte und lokale Variablen auf dem Stapel direkt unterstützen. Der 6502 ist hierfür nicht geeignet, da für eine einfache Hochsprachenanweisung wie "i := i + 2" sehr viele Befehle nötig sind, was zu Lasten der Geschwindigkeit geht und den Code stark aufbläht. Letzteres war auch ein Grund, warum z. B. UCSD-Pascal eine virtuelle Stackmaschine verwendete und nicht direkt nach Assembler kompilierte. Nur so war es möglich, umfangreiche Programme wie den Editor oder den Compiler vollständig in den knappen 64 kb Speicher zu laden. (Wie ich schon öfters schrieb, war die Ausführungsgeschwindigkeit eines kompilierten Pascal-Programms trotzdem viel höher als die eines Basic-Programms und erlaubte uns damals auch, kleine Actionspiele in Pascal zu schreiben.) Für einen neuen Retrocomputer bedeutet dies schlicht, daß dieser mindestens über eine 16 Bit-CPU verfügen sollte, um Zahlen wie z. B. XY-Koordinaten in einem Rutsch zu berechnen oder auch direkt auf lokale Werte auf dem Stapel zuzugreifen.


    Vom Wertebereich her dürfte eine 16 Bit-CPU als Grundlage für einen Rechner für die meisten Spiele bereits ausreichend sein. Dem Sprung auf 32 Bit liegt denn auch weniger der Wertebereich der Variablen zugrunde als vielmehr der größere Adreßraum, um Code und Daten gemeinsam unterzubringen. Möchte man möglichst zügig ein Programm entwickeln, wäre es von Vorteil, wenn die Entwicklungsprogramme Editor, Compiler und Debugger gleichzeitig zusammen mit dem Quelltext und dem Objektcode im Speicher liegen könnten, doch allein bei der Kombination aus Compiler und Quelltext überschreitet man die engen Grenzen des 64 kb-Adreßraums deutlich. Somit steht man dann wieder vor der Wahl: Nimmt man es in Kauf, daß man andauernd den Quelltext auf einen Datenträger speichern muß, damit dieser vom Compiler gelesen und in Objektcode umgewandelt auf dem Datenträger gespeichert wird, der dann von eben diesem geladen und ausgeführt wird usw., oder sagt man sich: "Nein, das muß ich mir nicht antun. Gib mir 32 Bit, und gut ist." Letztendlich sind es diese praktischen Fragen, die das Design eines Systems bestimmen, und nicht irgendwelche "Ich wünsche mir eine Hardware, die ... kann"-Träume.

  • So wie ich das verstanden habe, entspricht das auch dem gängigen Release/Debug-Modell, oder?

    Beim C#, mit dem ich mich zur Zeit hauptsächlich vergnüge, steht Debug für eine eindeutige Zuordnung von Stellen im Quelltext zu Stellen im Compilat. Release optimiert mehr, sortiert um usw.


    In meinem VB6 hieß Debuggen zusätzlich (bzw. einstellbar), dass Module erst bei Bedarf kompiliert wurden, und das vermisse ich sehr.
    Konsequenzen daraus:
    - Das Programm muss nicht komplett kompilierbar sein, Fehler in irgendwelchen Unterprogrammen sind OK, solange sie nicht aufgerufen werden.

    - Während des Debuggens waren mit kleinen Einschränkungen Änderungen im Programm möglich, ohne es zu beenden oder Variablen zu verlieren.

    - Auch der Programmcounter konnte mal eben verschoben werden. Wenn irgendein Unterprogramm beim 300. Durchlauf was komisches geliefert hat, dann hat man es einfach nochmal aufgerufen und zugesehen, was es rechnet.


    2. und 3. Punkt sollten im Prinzip auch bei vollständigen Compilaten schwierig, aber möglich sein, und zumindest in meinem vsCode +.Core finde ich das nicht.