Beiträge von Mike im Thema „3D-Grafik in V2 BASIC“

    Zitat von Mike

    Letztenendes war aber genau diese Schleife dann der Knackpunkt und genau die hatte ich dann später mal in Maschinencode übersetzt, wo dann die Arithmetikroutinen des Interpreters direkt aufgerufen wurden. In der Folge wurde dann diese Schleife um den Faktor 3 beschleunigt, zusammen mit dem restlichen Programm lag dann beim Ausgangsbild die Zeit bei ca. 90 Minuten. Ein anderer Koordinatensatz (mit 254 als maximale Rechentiefe) wurde z.B. von 2360 auf 840 Minuten beschleunigt.

    Zitat von JeeK

    Auch beachtlich. So ein Compiler ist nicht zu verachten.


    Hmm, nein, nix Compiler. Liebevoll selbstgeschriebener und dann assemblierter Maschinencode:


    Das ist bereits für den C64 und kam dann in der portierten Fassung des Mandelbrotgenerators in einem anderen Thread (Bitte melde dich an, um diesen Link zu sehen.) auch zum Einsatz. :)

    Außer daß I und N jetzt als 16 Bit unsigned Integer "deklariert" sind, macht diese Routine exakt dasselbe wie zuvor Zeile 17 in dem Programm - die Parameterübergabe für R und J übernehmen die beiden Routinen bei $AEFD (Check für Komma) und $AD8A (Ausdruck auswerten und nach FAC), so daß man die Routine mit SYS828,R(...),J(...) aufrufen und die Anzahl der tatsächlich stattgehabten Iterationen danach mit 'PEEK(3)+256*PEEK(4)' herausholen kann.

    P.S. Nicht wundern über die &-Zeichen bei den Hex-Konstanten. Das ist der Inline-Assembler von BBC BASIC. 8)

    Zitat von Tale-X

    Kleine Frage zur Codezeile: das Next dort wird nur dann ausgeführt, wenn die Then-Bedingung erfüllt ist? Dann müsste ja dann noch ein Next für den "Else"-Fall stehen. Wie stellst Du da sicher, dass ein zweites Next für die I-Schleife nicht zu einem Fehler führt (falls er im IF-Teil die I-Schleife komplett durchläuft)? Mir ist da keine saubere bzw. nicht umständlich aussehende Lösung eingefallen.


    Im Rest des Programms wird diese Schleife nicht fortgesetzt, und darum - richtig beobachtet - 'hängt' die Schleife zunächst, wenn die IF-Anweisung nicht (mehr) ausgeführt wird. Das ist aber weiter kein Problem, wenn man dann bei der nächst äußeren Schleife die Laufvariable explizit angibt. In diesem Fall sucht NEXT den Stapel nach der FOR-Anweisung mit der passenden Laufvariable ab und entfernt sauber alle 'hängenden', nicht abgeschlossenen Schleifen dazwischen. 8)

    Hier ist das komplette Programm (auf VC-20 mit MINIGRAFIK). Die 'Aufräum-Anweisung' ist das 'NEXT S' in Zeile 28:


    In einem ähnlichen Zusammenhang kann man z.B. auch aus einer offenen Schleife in einer Unterroutine direkt mit RETURN zurückkehren, ohne daß man dazu die Schleife vorher beenden muß.

    Hi, Jeek!

    Dein Beitrag ist mir erst jetzt aufgefallen (und das auch nur durch den Verweis in Tele-X's weiterer Umformung... :whistling:).

    Jetzt solltest Du die "Zeitersparnis" durch deine "Optimierungen" nur noch ins Verhältnis setzen zu der Zeit, die Du benötigt hast, um diese Änderungen ins Programm einzubringen. Und dann fällt die Bilanz durchgehend negativ aus, wenn man davon ausgeht, daß das Programm nur einmal laufen gelassen wird. :(

    Weiterhin leidet die Einsichtigkeit durch die Verwendung von Variablen anstelle von numerischen Konstanten ganz erheblich. Gerade der Ersatz von einstelligen Konstanten durch Variable lohnt sich (mit Ausnahme von - etwa - E=1 und E direkt als erste Variable definiert) fast überhaupt nicht, Null kann aber problemlos überall durch den Dezimalpunkt ersetzt werden. Ersatz von mehrstelligen und 'gängigen' Konstanten wie etwa mit V=53248 ist aber in Ordnung.

    Die "Deklaration" von häufig genutzten Variablen hingegen bringt durchaus etwas, wenn es um eine enge Schleife geht und im wesentlichen nur die Grundrechenarten im Spiel sind. Wovon man im aktuellen Beispiel aufgrund der SQR() und COS() Funktionen leider auch nicht sprechen kann. Ich hab' aber mal in einem anderen Programm (Apfelmännchen) die innere Schleife so erheblich beschleunigt:

    Code
    17 FORI=1TON:X2=X*X:Y2=Y*Y:IFX2+Y2<4THENXY=X*Y:X=X2-Y2+R:Y=XY+XY+J:NEXT


    Zusammen mit dem restlichen Programm *) brauchte das für das Ausgangsbild (die "Grundmenge") zunächst mal 195 Minuten. Als ich dann die Variablen X, Y, X2, Y2, XY, R und J (in dieser Reihenfolge) als erste Variablen deklariert hatte, fiel die Rechenzeit auf 156 Minuten! Dabei war es nicht nötig, die Laufvariable I und den Endwert N früh zu deklarieren, da FOR einen Zeiger auf seine Laufvariable ermittelt und so immer schnellen Zugriff hat, und der Endwert auch nur einmal ausgewertet wird und dann mit auf den Stapel geht. Aber als ich dann die Konstante 4 auch noch durch eine Variable ersetzt hatte, wurde das Programm schon wieder langsamer!

    Letztenendes war aber genau diese Schleife dann der Knackpunkt und genau die hatte ich dann später mal in Maschinencode übersetzt, wo dann die Arithmetikroutinen des Interpreters direkt aufgerufen wurden. In der Folge wurde dann diese Schleife um den Faktor 3 beschleunigt, zusammen mit dem restlichen Programm lag dann beim Ausgangsbild die Zeit bei ca. 90 Minuten. Ein anderer Koordinatensatz (mit 254 als maximale Rechentiefe) wurde z.B. von 2360 auf 840 Minuten beschleunigt. :)

    Um noch mal zum Hut-3D-Plotter zurückgekommen: mein Originalprogramm war ja auch schon nicht ganz ohne Optimierungen. Zum Beispiel muß man den Bitwert zum Einmaskieren ja nicht unbedingt mit angezogener Handbremse (sprich: mit 2^(7-(XPAND7))) berechnen. Auch die Adreßberechnung arbeitet ja bereits mit einer Tabelle, anstatt ständig den vollen Ausdruck 'AD=8192+320*INT( YP/8 )+8*INT( XP/8 )+(YPAND7)' auszuwerten (mit 'XPAND504' geb' ich dir aber Recht... hab' ich auch schon mal verwendet... :whistling:)

    Ansonsten gilt nach wie vor: Experimentieren macht Spaß! ^^

    Gruß,

    Michael

    *) das war auf dem VC-20, und da hatte ich den Grafik-Teil bereits mit einer eigenen BASIC-Erweiterung implementiert!

    P.S. so ein "nosmiley"-Tag für Fließtext wär' manchmal ganz brauchbar. Ständig wird '...8 )' durch '...8)' ersetzt...

    Zum Experimentieren reicht BASIC allemal.

    Eine BASIC-Erweiterung bringt hier noch den Vorteil, daß man sich nicht mehr um die Implementierung der Grafikbefehle zu kümmern braucht (siehe Zeilen 10 bis 12, 16 bis 18, 27 [SYS58648 zur Rückkehr in den Textmodus] und 29) und sich stattdessen bei dieser Anwendung auf die Mathematik konzentrieren kann.

    Im übrigen hab' ich Bitte melde dich an, um diesen Link zu sehen. auch schon vor Jahren auf dem VC-20 mit MINIGRAFIK geschrieben und dann heute zunächst mal in BASIC V7 die Koordinatendarstellung/Auflösung von 160x192 auf 320x200 angepaßt ... und dann den Code rückwärts nach V2 portiert. :D

    Och, da geht schon was. Gezeichnet wird hier ein Hut in Schräg-Perspektive:


    Warp-Mode oder Maximum Speed > No limit sind auch hier empfehlenswert. ^^