Optimierungsgrad KERNAL /BASIC - fiktiver Talk

Es gibt 337 Antworten in diesem Thema, welches 62.645 mal aufgerufen wurde. Der letzte Beitrag (16. September 2017 um 00:34) ist von Boulderdash64.

  • Puh, das wäre aber dann wohl entweder ein ganz neuer Variablentyp, oder ein neuer Operator wie der * in C. Da Pointer auch nicht grade als ultimativer Segen aller Programmiersprachen bekannt sind, würde ich da wohl eher Basic-nah bleiben wollen.

    Dafür habe ich volles Verständnis, denn mit nichts kann man sich so herrlich ins Knie schießen wie mit Pointern .. allerdings .. haltaus .. nein, eine kleine Plattform hört nicht auf, Widerstand zu leisten, und kommt mit einer noch besseren Möglichkeit: Dem POKE! :wink:

    Es stimmt schon. C++ versucht verzweifelt, die nackten Pointer loszuwerden und durch Referenzen zu ersetzen. In JAVA, C#, etc. gibts überhaupt nur Referenzen, und so weiter. Man muss sich nur anschauen, was der Nachteil ist: Einiges an Performance und noch viel mehr an Speicherbedarf.

    Da würde ich sagen: beim C64 kann man eh nur maximal 64kb abstürzen, da wähle ich lieber den Vorteil und nehme das Risiko in Kauf. :wink:

  • wie dein Beispiel ja auch locker mit der (noch) nichtvorhandenen Modulo-Funktion behende zu Werke geht

    Huch :saint:

    ────────────────────────────────────────────────────────────
    Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen.
    ────────────────────────────────────────────────────────────

  • Also, der ideale Bitmap-Bereich für Basic ist wenn sich die Bitmap unter dem Kernal befindet.

    Zum Löschen der Bitmap in Basic verwendet man am besten die Lösch-Routine des Dim-Befehls.
    Schneller geht es in Basic wohl kaum.

    Die Größte Leistungsbremse in Basic sind vermutlich die Fließkomma Variablen.
    Ein System auf 2-Byte Integer beruhend müßte einiges an Leistung bringen.
    Das wäre also die Umstellung der Standard-Variablen auf INT´s.
    Fließkomma-Berechnungen sind ja bei der Programmierung eher selten.

    Schönen Gruß.

  • Einen großen Gewinn an Speicherplatz bekommt man als Basic-Programmierer natürlich auch durch das ROM-RAM Unterprogramm PostBitte melde dich an, um diesen Link zu sehen..
    Da man als Basic-Programmierer dadurch die oberen 16kB des C64 als Grafikspeicher für Zeichen, Bitmap, Sprites und Bildschirme nutzen kann. Und das ohne Hauptspeicher-Verluste.

    Schönen Gruß.

  • Edit 2: oder als 2dimensionales Array, wenn Platz für so eine Implementierung ist. Dann übernimmt der Interpreter die komplette Adressberechnung incl. $E000-Offset:
    10 µ(X,Y)= 1
    20 µ(X,Y)= 0

    Diese suggestive Schreibweise für Punkt-Setz/Lösch-Befehle sieht zwar nett aus, und liefert auch eine interessante "Blaupause" für den Fall, daß man eine Auslesefunktion gleich aussehen läßt. Mit einer zweimal geschachtelten FOR-Schleife lassen sich dann Bitmap-Inhalte easy kopieren:

    Code
    FOR DY=0 TO M-1
    FOR DX=0 TO N-1
    µ(X1+DX,Y1+DY)=µ(X2+DX,Y2+DY)
    NEXT
    NEXT

    (evtl. muß die Kopierrichtung in der x-Achse oder y-Achse umgekehrt werden, wenn die Bereiche überlappen)

    Aaaber: für den dringend nahegelegten Fall, daß man eine Linienziehroutine mit hineinnimmt, gibt es keine einfache Erweiterung der Syntax für den zweiten Koordinatenpunkt.

    Für MG sieht der Punktsetzbefehl darum anders aus: @<farbe>,<x>,<y> wobei die Parameter Zahlen, einfache Variablen oder numerische Ausdrücken sein dürfen. Der Linienziehbefehl sieht dann einfach so aus: @<farbe>,<x1>,<y1> TO <x2>,<y2>. Ich habe das "@"-Zeichen als Marker für alle neuen Befehle von der Original-Version von MG aus Kompatibilitätsgründen übernommen - und "At" ist auch wiederum eine suggestive Schreibweise. :)

    Es gibt aber schon die Funktion @(X,Y) zum Auslesen, so daß der "aktive" Teil obiger Kopierschleife in MG jetzt wie folgt aussieht:

    Code
    @@(X2+DX,Y2+DY),X1+DX,Y1+DY
  • Die Größte Leistungsbremse in Basic sind vermutlich die Fließkomma Variablen.
    Ein System auf 2-Byte Integer beruhend müßte einiges an Leistung bringen.
    Das wäre also die Umstellung der Standard-Variablen auf INT´s.
    Fließkomma-Berechnungen sind ja bei der Programmierung eher selten.

    Klingt sehr gut. Es spricht ja nichts dagegen, trotzdem auch Floats anzubieten, aber sie zum Standard zu machen, ist tatsächlich dämlich. Allerdings ist das bereits im Ur-Basic so gewesen (dass es nur Fließkomma-Zahlen gab) das wirklich nur als Lernhilfe und nie als ernsthafte Programmiersprache konzipiert worden ist.

  • Nochmals. Bitte hört auf den Troll zu füttern.

    Was soll die Quatschbehauptung, daß "Fließkomma-Berechnungen bei der Programmierung ja eher selten seien."? Da kann man noch nicht einmal ernsthaft drauf eingehen. BASIC ist durchaus damals vom Dartmouth College dafür konzipiert worden, daß auch kompliziertere mathematische Probleme damit angegangen werden können. Sogar eine Syntax für Matrix-Operationen, incl. Matrizen-Multiplikation war da mit drin. Die Erfinder von BASIC können nichts dafür, daß M$ und Co. damals aus Speichermangel alle guten Sachen aus BASIC rausgeworfen hatten bis hin zu dem Punkt BASIC so weit zu kastrieren, daß es echt nur noch mit 16-Bit-Zahlen rechnet.

    Für die Programmruinen, die BIF verbricht, mag das ausreichen. Da würden aber auch schon Variablen genügen, die nur den Wert 0 annehmen können. Laufen tun seine Machwerke so oder so nicht. Es lohnt sich also gar nicht ihn irgendwie hier in die Diskussion mit einzubeziehen.

    So. Das mußte jetzt mal raus.

  • Hmm, weisst du zufällig noch, wieviel Bytes diese Label-Erweiterung beansprucht hat?
    Das neue ROM soll ja nicht zu fett werden

    Das müsste ich aus diversen Erweiterungen, die ich damals gemacht hatte, rausrechnen - nicht ganz einfach. Ausserdem hatte ich das ja ins Exbasic eingebaut und nicht in's normale Basic.
    Aber soviel kann das eigentlich nicht gewesen sein: eine eigener Token für das Setzen eines Labels (Label-Kommando) und eine Erweiterung der GOTO/GOSUB-Routine, damit die Labels interpretiert werden. Natürlich gab es damals keine Optimierung, das heisst bei jedem Sprung wurde der gesamte Basic-Text nach dem Label durchsucht.

  • Aaaber: für den dringend nahegelegten Fall, daß man eine Linienziehroutine mit hineinnimmt, gibt es keine einfache Erweiterung der Syntax für den zweiten Koordinatenpunkt.

    Der Basic-Interpreter ist ja nicht auf eine bestimmte Anzahl Parameter festgelegt, siehe Mid$ oder on X goto.
    Der kann ja prüfen, ob ein , oder eine ) kommen.

    Was soll die Quatschbehauptung, daß "Fließkomma-Berechnungen bei der Programmierung ja eher selten seien."? Da kann man noch nicht einmal ernsthaft drauf eingehen.

    Hätte ich jetzt aber auch mal sehr angenommen, dass Int häufiger benutzt wird.
    Im Zweifel kann man ja die Listings der 64er überfliegen, oder alle Treffer in VB-Programmen nach "AS Integer", "AS Long", "AS Single", "AS Double" zählen lassen.

  • daß es echt nur noch mit 16-Bit-Zahlen rechnet.

    Du meiinst, dass es "echt gerade nicht mehr mit 16-Bit-Zahlen rechnet"?

    Gerade das Fehlen der 16-Bit-Integer ist ja eine der größten Performance-Bremsen gewesen. Eine Erweiterung um Integer-Arithmetik müsste einen ziemlichen Performance-Gewinn bringen, die Syntax ist ja mit der %-Schreibweise bereits vorhanden (z.B. A%). Allerdings müsste man für den neuen Datentyp die gesamte Formelauswertung neu schreiben. Trivial ist das nicht.

  • Hätte ich jetzt aber auch mal sehr angenommen, dass Int häufiger benutzt wird.
    Im Zweifel kann man ja die Listings der 64er überfliegen, oder alle Treffer in VB-Programmen nach "AS Integer", "AS Long", "AS Single", "AS Double" zählen lassen.

    Wenn ich eine höhere Programmiersprache benutze, setze ich die Verfügbarkeit von Fließkommazahlen voraus.

    16-Bit-Integer-Zahlen kann ich auch in Assembler haben, dazu brauche ich dann keinen irgendwie gearteten Überbau mit dem Überrest eines BASIC-Interpreters.

    Zitat von detlef

    Du meiinst, dass es "echt gerade nicht mehr mit 16-Bit-Zahlen rechnet"?

    Doch. Ich meinte wirklich, daß BASIC-Dialekte existieren, die *wirklich* *nur* *mit* 16-Bit-Zahlen rechnen. Das BASIC vom Apple I oder ZX80 etwa. Wie gesagt - dann ist man bereits so tief gesunken, daß man den Sprachen-Überbau gleich ganz weglassen kann.

    Wir hatten hier im Thread auch schon die Diskussion, vollwertige Integer-Routinen zusätzlich mit reinzunehmen. Quizfrage: was passiert dann bei PRINT 1/3 ? ... willst Du das wirklich?

  • Noch 2 Gedanken:
    Für die Ausgabe von Strings aus dem ROM wurden glaub ich alle Methoden angewendet:
    -Bit 7 als Endezeichen
    -Nullbyte als Endezeichen
    -Nach Länge.
    Vielleicht lässt sich das vereinheitlichen und etwas sparen.


    Die Stringverarbeitung könnte ein paar Sonderfälle beachten, um die GC zu verzögern.
    Bisher wird immer Speicher für einen neuen String reserviert, auch wenn der alte eigentlich genug Platz für den neuen Inhalt bietet.
    Und wenn erkannt würde, dass eine Zuweisung in einem String landet, der eh am Ende des Stringspeichers steht, dann könnte der neue Inhalt auch ohne Garbage geschrieben werden.
    (Bin mir aber nicht 100%ig sicher, dass temporäre Strings überschrieben werden dürfen, sobald etwas in eine echte Variable geschrieben wird).


    Dabei fällt mir auf, dass es evtl. geschickter wäre, Variablen von hinten nach vorne und Strings von vorne nach hinten im Speicher abzulegen.
    Viele Operationen fügen einem String immer wieder was in Häppchen hinzu. Ein CONCAT-Befehl könnte das etwas hübscher lösen.
    (Bzw. wäre das was für den anderen Thread)

  • Ist bekannt , warum überhaupt die Strings "von oben nach unten wachsen"?
    Ist das eine historische Anleihe bei Unix-Systemen bzw. dem sogenannten Globalen Heap?

    Deinen Vorschlag die Numerischen und alphanumerischen Bereiche zu tauschen im Speicher sehe ich in einer Tradition mit dem Gedanken, Programmzeilen und Strings "gleich" zu behandeln ... und hier würden sie sogar einen homogenen Block bilden (würde für nullterminierte Strings sprechen ....) ?

    Das mit den Sonderfällen leitet über zur Numerik.

    Das Applebasic von S. Wozniak ist ein gutes Beispiel dafür, dass man locker mit dem begrenzten Platz auskommt, wenn man sich auf Pseudo-Lösungen einlässt: das Weglassen von Funktionalität in dem Fall echte Real-Zahlen... pfft, keine Kunst würde ich da sagen. Mikes Gedanke dass Fließkommazahlen zum Brot-und-Butter-Geschäft bzw. zum Kernbestand einer Hochsprache gehören, wird von mir unterstützt.

    Aber die Algorithmen der Fließkomma-Arithmetik bzw. zum Rechnen überhauot sind seit 1975 nicht stehengeblieben. Ich kann mir vorstellen dass im Math-Package auch ein paar Sonderfälle mehr erkannt und berücksichtigt werden könnten. Die Unterscheidung Real / Integer scheint eh obligatorisch. Zum Dividieren und Multiplizieren, auch zur SQR gibt es eine Reihe sehr interessanter Algorithmen ...

  • Bei Floating Point und 6502 trifft man immer wieder den Bitte melde dich an, um diesen Link zu sehen.
    Ist dieser Code auch im C64 gelandet?
    Wie verhält er sich zum Code im C64?

    Codebase bietet auch ein paar Bitte melde dich an, um diesen Link zu sehen. an, die aber viel Speicher fressen. An den Routinen selbst scheint aber nichts getan worden zu sein.

  • Die Fließkommazahlen rauszuschmeißen mein ich natürlich nicht.
    Aber eine bessere Integer Unterstützung würde wohl doch mehr an Geschwindigkeit bringen.

    Mit einem %Zeichen könnte man theoretisch die Float-Berrechung einleiten oder die Integer Berechnung.

    :print %2.2+2.2:

    Theoretisch könnte man auch von Integer auf Float-Rechnung umschalten z.B. mit einem Befehl:
    float 1:float 0

    Schönen Gruß.

  • Bei Floating Point und 6502 trifft man immer wieder den Code von Rankin/Woz.
    Ist dieser Code auch im C64 gelandet?
    Wie verhält er sich zum Code im C64?

    Der Code von Rankin / Woz scheint 32-Bit-Reals mit 23/24 bit Mantisse zu verarbeiten, jedenfalls schließe ich das aus dem Zähler (für 3 Bytes abzuklappern) der mittendrin gesetzt wird; das entspräche bei Gates/Allen/Davidoff der ursprünglichen Version, sog. 6-Digit-Basic (benannt nach der Genauigkeit der Reals in Dezimaldarstellung, im Gegensatz zu 9-Digit-Basic wie es im Commodore eingesetzt wurde, mit 40-bit-Speicherformat.)

    Die 32-Bit-Reals haben 3 Bytes Mantisse. Soviel verarbeitet auch das ursprüngliche Altair-Basic.
    Rankin / Wozniak verwenden nicht den Trick mit dem weggelassenen 1-bit am Anfang der Mantisse.

    Edit: hier stand voreilige Deutung. Hatte DIV zu MUL zugeschlagen

  • Jedenfalls ist das Ergebnis einer Multiplikation grob falsch, sobald einer der Faktoren zwei aufeinanderfolgende Nullbytes in der Mantisse aufweist, ein Zwischenergebnis wird dann (in einer wiederbenutzten Routine übrigens!) fälschlicherweise um ein Bit zuviel geschoben. Zu sehen z.B. hier:

    Kann es sein, dass beim Übergang von 32-Bit-Real-Speicherformat mit 3 Bytes Mantisse auf 4 Bytes Mantisse (9-digit-Basic) hier etwas schiefgegangen ist bzw. übersehen wurde?

    Scheint ja fast mit Händen greifbar:
    Der Programmierer dachte sich möglicherweise, sind beide übrigen Folgebytes = 0, also das zweite und dritte = letzte (bei deiser Implementierung!) ist in dieser Schleife nichts mehr zu tun und man kann vorzeitig den RTS anspringen. (Optimierung?) Auf dem 8080-Prozessor wäre das vermutlich mit einer einzigen Vergleichs-/Test-Instruktion abzuhandeln gewesen. (16 bit breit)

    Und dann kam aus dem Nichts ein 4. Byte daher für die Mantisse.
    Dann hätte man entweder die letzten 3 Bytes auf Null abprüfen müssen, oder nur die letzten beiden. Aber halt nicht die mittleren beiden ...

  • Ist bekannt , warum überhaupt die Strings "von oben nach unten wachsen"?

    Falsche Frage. Du willst wissen, warum MS-Basic überhaupt einen eigenen String-Speicher hat- Sinclair-Basic kommt ja auch ohne aus. Es gibt zwar einen Arbeitsbereich für temporäre Strings und Formeln, aber der wird nach jedem Befehl zurückgesetzt. Daher gibts auch keine lästige Garbage Collection, die den Rechner scheinbar einfrieren läßt.

    Wie macht das eigentlich die 8080-Version von MS-Basic? Die muß mit dem Prozessorstapel ja noch einen dritten dynnamischen Speicherbereich zügeln.

    A prospos Sinclair Basic...

    Nachtrag berechneteb GOTO:

    Sinclair hat das, und es führt keineswegs zu endgültig verspaghettitem Stolpercode. Denn erstens wird es fast nie benutzt. Zweitens ist es sowohl mühsam wie langsam und unübersichtlich, auch nur so eine Art Prozedurvariablen zu erzeugen und auch nur für die wichtigsten Sprungziele eine Variable zu belegen. Nichtmal als Ersatz für das nicht implementierte ON...GOTO qwird es allzu oft genutzt; i.d.R. finden sich dann Ketten von IF auswahl=x THEN GOTO mache_x_jetzt

    Wenn es denn aber mal vorkommt (in der Form GOTO auswahl*500+1000) dann meist in sehr gut strukturierten Programmen, fein sortiert in 500er-Blöcken etc. Und renumbern kann man das auch- man macht das halt für jeden Funktionsblock einzeln udn beläßt die erste Zeile tunlichst an Ort und Stelle. Ein einfaches RENUMBER 10 führt dagegen unweigerlich zu Chaos und Verspätung. Die Formeln von berechneten Gotos läßt der Befehl übrigens einfach wie sie sidn; neu numeriert werden nur GOTO mit einer einzelnen Zahlenkonstante.

    Benannte Prozeduren gibts dann übrigens bei BETA BASIC, auf Zeilennummern kann man aber auch hier nicht verzichten. Dazu ist der Bildschirm einfach zu klein und zu langsam- selbst beim C64- als daß man problemlos durch ein längeres Programm blättern könnte... klar, es gibt Turbo Pascal mit seinem Wordstar-Clone-Editor, aber Programme mit tausenden Zeilen mag man damit wirklich nicht auf 8-bittern bearbeiten.

    KI-Verwendung in diesem Posting: Rechtschreibkontrolle des Browsers.
    Abweichungen aufgrund des technischen Fortschritts oder individueller Vorlieben vorbehalten.

  • Ich als alter c64 Turbo Pascal User kann Dir sagen, dass solche Programme eh nicht am Stück in den Speicher passen... ^^

    Wenn Du sagst, dass der berechnete gosub Befehl eh kaum genutzt wird, warum dann einbauen?
    Dann doch lieber einen Mechanismus um eigene benannte Prozeduren zu definieren. Dann könnte sich bei Bedarf jemand den Befehl selbst schreiben oder nachladen. Wird er nicht gebraucht, dann belegt er auch keinen Speicherplatz.

  • Ich als alter c64 Turbo Pascal User

    Äh .. spinn ich schon total? Turbo Pascal für C64? Ich kannte Oxford-Pascal, Profi-Pascal, G-Pascal, Kyan-Pascal .. Abacus-Pascal .. aber Turbo-Pascal? Wo gibts denn das?