Hello, Guest the thread was viewed22k times and contains 140 replies

last post from TD1334 at the

BASIC-Code beschleunigen/optimieren

  • War auch mein Eindruck. Hatte dann aber öfter mal, dass es langsamer war. Ich weiß aber nicht warum ? Ob es an der Größe der Zahl lag oder Postition im

    Variablenspeicher.


    Danke für deine Messung

  • ich habe das mal mit meinem Speedo Analyzer ausprobiert und ich konnte keine Unterschiede in den Taktzyklen erkennen.


    Muss das nochmal mit der V1.1 testen. Liege aber schon im Bett vorm TV (Klub WM), also erst morgen 😌

  • ich habe das mal mit meinem Speedo Analyzer ausprobiert und ich konnte keine Unterschiede in den Taktzyklen erkennen.

    Ich glaube, der Unterschied hängt daran, ob die zu vergleichenden Werte unterschiedliche Größenordnungen haben. Einer von beiden muss ja dann angepasst werden. Die Details dazu habe ich mir im BASIC-ROM noch nie angeschaut. Deswegen kann ich dazu auch nicht viel mehr sagen.

  • TD1334 und berni Kann man Eure Geschwindigkeitsmesser irgendwo bekommen? Womöglich mit Quellcode? Wollte so was selbst mal machen, für den Kassettenpuffer, SYS X für Start und SYS Y für Stopp, und mit einem Parameter, der angibt, ob dabei Interrupt und/oder VIC abgeschaltet werden sollen. Ich weiß ja nicht, wie Ihr das gemacht habt.

  • TD1334 und berni Kann man Eure Geschwindigkeitsmesser irgendwo bekommen? Womöglich mit Quellcode? Wollte so was selbst mal machen, für den Kassettenpuffer, SYS X für Start und SYS Y für Stopp, und mit einem Parameter, der angibt, ob dabei Interrupt und/oder VIC abgeschaltet werden sollen. Ich weiß ja nicht, wie Ihr das gemacht habt.

    Tja, meine Stopuhr wird es in der kommenden Ausgabe der DitgitalTalk als Beigabe geben. Es fühlt sich irgendwie blöd an, die vorher schon hier zu veröffentlichen. Allerdings zieht sich das mit der Ausgabe jetzt auch schon ewig hin. Redaktionsschluss war vor 3 Monaten und seit gefühlt 2 Monaten ist alles fertig und keiner weiß, warum es nicht weitergeht.


    Ich denke, ich werde es so machen: Wenn nach meinem Urlaub die DT immer noch nicht erschienen ist, werde ich die Stopuhr hier vorab veröffentlichen; weil irgendwann ist mit der Warterei dann auch gut. (Dann, oder wenn die DT erscheint, wird es auch den Source-Code auf GitHub geben.)


    Ich weiß grad gar nicht mehr genau, wie ich das genau mache. Ich hab' den IRQ auf den Rasterstrahl umgebogen (und den normalen IRQ abgeschaltet). Bildschirm blieb an. Der IRQ wird dann immer bei einer bestimmten Rasterzeile aufgerufen. Dort wird ein Zähler um eins erhöht, und zwar mit einem Code der immer exakt gleich viele Zyklen dauert. Dadurch kann man ausrechnen, wie viele Taktzyklen eines Bildschirmaufbaus vom normalen Programm genutzt werden.


    Wenn das Programm endet, wird noch die Rasterzeile gespeichert und zwar 80 mal oder so. Ich hatte eine Formel gefunden, wie man daraus dann nicht nur die Rasterzeile, sondern auch den Taktzyklus in der Zeile (also sozusagen die Rasterspalte) ausrechnen kann. Das geht aber nur gut, wenn man nicht im Badline-Bereich endet. Für mein Anliegen damals (exakt eine Minute zu messen) war das mehr als genug; nach exakt einer Minute ist der Rasterstrahl nämlich außerhalb des Badline-Bereichs. :)

  • Redaktionsschluss war vor 3 Monaten und seit gefühlt 2 Monaten ist alles fertig und keiner weiß, warum es nicht weitergeht.

    Au weia. Ich ahne etwas.


    Dein Tool läuft so schnell, dass sich relativistische Effekte ergeben und der Release-Zeitpunkt immer weiter ausgebremst wird. Meiner Meinung nach hilft nur eins: Du ziehst dein Programm wieder aus der Digital Talk zurück und du wirst feststellen, dass es schon letzten Monat veröffentlicht wurde!

  • TD1334 und berni Kann man Eure Geschwindigkeitsmesser irgendwo bekommen? Womöglich mit Quellcode? Wollte so was selbst mal machen, für den Kassettenpuffer, SYS X für Start und SYS Y für Stopp, und mit einem Parameter, der angibt, ob dabei Interrupt und/oder VIC abgeschaltet werden sollen. Ich weiß ja nicht, wie Ihr das gemacht habt.

    Ich nehme an, dass dich der Quellcode interessiert.

    Ich will erst noch etwas Feintuning machen. Aber meine Sache passt aktuell nicht in den Kassettenpuffer. Ich glaube aktuell brauche ich 13xx Bytes an Speicher und dann benutze ich ab $e000 den Speicher für maximal 1023 Basic Zeilen, Ich nutze 8 Byte pro Zeile, 2 Byte für Zeilennummer, 2Byte für den Zäher und 4 Byte für den 32 Bitwert der Taktyklen, das reicht für Über eine Stunde für eine Zeile.

    Ich denke 1023 Zeilen reichen, weil mein Speedo ja dafür gedacht ist um Testroutine auf ihre Geschwindigkeit zu überprüfen und nicht fertige Mega-Projekte zu analysieren.


    Gib mir noch ein paar Tage, dann kannst du den Code von mir haben. Entweder hier oder ich schieb ihn hoch auf meine Github Seite.

  • In den meisten Fällen nicht.

  • was mich mal interessieren würde: Wenn ich meinen Basic-Code optimiere und diesen dann durch einen Compiler übersetzen lasse. Ist der Maschinencode dann auch schneller, als wenn man einen nicht optimierten Code durch einen Compiler übersetzen lässt?

    In der Tat, kann man das wohl nicht allgemeingültig beantworten. Sagen wir so, es gibt sicher Fälle, wo das so ist.

    Wenn ich etwa so etwas habe:

    FOR I=0 TO 7: B(I) = 2^(7-I): NEXT

    und das optimiere zu

    V=1:FOR I=7 TO 0 STEP-1: B(I)=V: V=V+V: NEXT

    Das sind jetzt nur 8 Durchläufe, aber es wären ja umfangreichere Dinge auch möglich, wo das dann schon ins Gewicht fallen könnte.

    Also es hängt wohl von der konkreten Optimierung ab. Die Sachen, die "nur" die Interpreter-Laufzeit optimieren wirken sich beim Compiler nicht aus, alles was eher Richtigung algorithmische Optimierung geht schon eher.


    Zu einem gewissen Grad hängt das auch von den Optimierungsfähigkeiten eines Compilers ab.

    Ein

    IF A>0 AND A < 40 THEN ...

    wird mit

    IF A>0 THEN IF A < 40 THEN ...

    auch bei jenen Compilern schneller, die nicht eine bedingte Auswertung erkennen und von sich aus die Kaskade wie im 2. Beispiel erzeugen.

  • Das macht keiner, nicht einmal meiner. Ich habe es mal versucht, aber das Problem ist, dass in BASIC V2 nicht unterschieden wird, ob logisches AND oder bitweises AND "gemeint" ist. Hier hatten wir das mal diskutiert: Die Fehler des Basic V2

  • Ein

    IF A>0 AND A < 40 THEN ...

    wird mit

    IF A>0 THEN IF A < 40 THEN ...

    auch bei jenen Compilern schneller, die nicht eine bedingte Auswertung erkennen und von sich aus die Kaskade wie im 2. Beispiel erzeugen.

    Und an dem Beispiel kann man dann auch schön sehen, dass es auch von den konkreten Daten abhängt, mit denen der Algorithmus dann später gefüttert wird.

    Wenn A ganz oft Werte kleiner 0 hat, dann steht da schon die beste Optimierung.

    Wäre aber A zum Beispiel ganz oft größer als 40, dann wäre es besser erst A<40 zu prüfen.

  • Wenn A ganz oft Werte kleiner 0 hat, dann steht da schon die beste Optimierung.

    Wäre aber A zum Beispiel ganz oft größer als 40, dann wäre es besser erst A<40 zu prüfen.

    Abgeblich macht ja die Java VM so Zeugs, und zwar nicht beim compilieren, sondern während der Code läuft: Da wird einfach mitgezählt. Da der Compiler in der VM integriert ist, kann die dann ggfs. umsortieren. Hab' ich zumindest mal gehört; ich hab' aber keine Ahnung ob das auch stimmt...

  • Und an dem Beispiel kann man dann auch schön sehen, dass es auch von den konkreten Daten abhängt

    Genau, und bei solchen Dingen wie mit den zu erwartenden Daten muss man beim Programmieren auf jeden Fall selbst mitdenken. Wenn ich z.B. weiß, dass die Daten gar nicht größer als 39 werden können, frage ich das auch nicht ab. Ich denke aber, dass das in der Regel nur der Autor wissen kann. Empirische Daten, und wenn sie auch 1000-mal hintereinander unter 40 liegen, sind keine Sicherheit. Und einer KI würde ich diese Entscheidung, ob ich "< 40" abfragen muss, auch nicht überlassen.


    Diese Überlegungen sind primär das, was ich mit "algorithmischer Optimierung" meinte. Vielleicht sollte man dabei eher von "semantischer Optimierung" sprechen. Es war ja nicht unbedingt gemeint, dass man erst einen komplett neuen Floodfill-Algorithmus oder ähnlich erfindet.

  • Genau, und bei solchen Dingen wie mit den zu erwartenden Daten muss man beim Programmieren auf jeden Fall selbst mitdenken. Wenn ich z.B. weiß, dass die Daten gar nicht größer als 39 werden können, frage ich das auch nicht ab.

    Wobei ich mal vorsichtig "Jain" sage. Ich weiß wie du es meinst und stimme vom Prinzip logischerweise zu. Aber auf der anderen Seite prüfe ich in meinen Anwendungen tausende von Dinge, die eigentlich gar nicht sein können und dann komischerweise plötzlich doch so waren (weil ich natürlich irgendwo anders etwas falsch gemacht hatte, weil die Daten "falsch" waren oder weil mal die von mir genutzen Bibliotheken fehlerhaft waren. Insofern finde ich es für mich als Programmier auch als sehr große Kunst zu wissen, wo man doch etwas prüfen sollte, obwohl das eigentlich gar nicht sein kann.) Und ich bin überrascht, wie lange bzw. spät solche Test zum Teil erst anschlagen. Da hatten schon tausende von Leuten meinen Quellcode benutzt, bei allen hat es mehrere Jahre funktioniert, und plötzlich meldet sich Kunden, dass meine Überprüfungen, die eigentlich gar nicht sein können, angeschlagen hatten. Es konnte eben doch sein :-(

  • Ja, das mit Java habe ich auch schon mal gelesen. Ich habe mal gelesen, dass einige CPUs solche Dinge sogar können.

    Viele neuere Sprachen mit JIT-Compiler/VM machen das, neben Java z.B. auch JavaScript (bzw. mindestens die besseren JavaScript-Runtimes wie z.B. Chromes V8). Merkt man u.a. daran, dass lange switch-Statements oder entsprechende if...then...else-Ketten "automatisch" in die optimale Reihenfolge gebracht werden, während man bei anderen Sprachen immer aufpassen sollte, im Quellcode auf den häufigsten Fall zuerst zu prüfen.


    CPUs machen sowas aber nicht, Du meinst vielleicht Sprungvorhersage oder Speculative Execution, das ist nochmal andere Magie, für die es auf Compiler/Programmiersprachenebene keine rechte Entsprechung gibt.

  • Hm naja, das ist eigentlich was leicht anderes. Likely und unlikely beeinflussen, welcher Code im RAM nachher "geradeaus" liegt (also ohne Sprung erreicht wird). Die Sprungvorhersage des Prozessors dagegen soll gerade dafür sorgen, dass auch eben Sprünge "kostenlos" (ohne Pipeline-Stalls) ablaufen, bzw. eben die vorhergesagte Sprungrichtung. Die Sprungvorhersage macht z.B. auch Schleifen (bzw. den impliziten Rücksprung darin) schnell, wofür es likely/unlikely gar nicht gibt.


    Likely/unlikely legen die Dinge also passend hin, während die Sprungvorhersage den Raum krümmt. :)