Hallo Besucher, der Thread wurde 308k mal aufgerufen und enthält 2099 Antworten

letzter Beitrag von oobdoo am

Heute so gecodet...

  • Mein memset Replacement ist gestern erstmal fertig geworden und ich bin recht zufrieden damit. :D


    Ich hatte das schon mal vor einem Jahr angefangen, weil ich ausprobiert hatte, ob man den "movem.l" nicht für sowas benutzen könnte. Ich war total begeistert von meiner genialen Idee und wie schnell das war. Als ich dann aber gegen das originale memset getestet hatte, war ich etwas schockiert. Meine geniale Idee war wohl doch nicht so genial und schnell wie gedacht, denn memset war schneller. :X Darauf habe ich es dann sein gelassen.

    Jetzt bin ich es nochmal angegangen, weil ich die Funktion brauche und diesmal hats geklappt. Meine Version ist schneller.

    Bei kleinen Grössen (bis ca. 20 Bytes) bin ich fast 60% schneller. Bei mittleren Grössen sinds dann ca. 10-30%, bei ca. 128 Bytes sind es immer noch ~8%. Logischerweise konvergiert dass dann, da bei sehr grossen Blöcken (z.B. 10KB) die Geschwindigkeit annähernd gleich wird (aber trotzdem noch etwas schneller). Ist aber zu erwarten, da das Setup im Vergleich zum eigentlichen Fill-Loop immer weniger ins Gewicht fält.

    Falls es jemand ausprobieren will, der Code ist hier: https://github.com/skeetor/amiga-utils, derzeit noch im "development" Branch. Da gibts im Project Verzeichniss dann auch ein Projekt TestMemfill, welches prüft ob es keine Bufferoverflows gibt und die Geschwindigkeit zu memset vergleicht.

  • In meiner library gibts auch eine snprintf style Funktion in M68000 Assembler, welche nicht nur deutlisch schneller als die C Version ist, sondern auch wesentlich sicherer. Die Funktion garantiert immer ein 0 Byte und garantiert auch keine Bufferoverruns. Die 0-Byte Garantie funktioniert nur dann nicht wenn als Bufferlänge 0 übergeben wird (dann gibts ja keinen Platz u das zu schreiben ;)).

    Es wird immer die Anzahl der Zeichen zurückgeliefert die für die gesamte Ausgabe notwendig ist. Ist der Buffer zu klein, wird der Rest des Strings nicht mehr geschrieben, sondern nur noch gezählt, so dass der Aufrufer weiss wie lange der Buffer sein müsste. Man kann auch einen nullpointer übergeben um die notwendige Länge zu ermitteln, was aber nicht zwingend notwendig ist.


    Die Funktion kann auch mit '%b' Binärzahlen ausspucken, allerdings unterstütze ich im Moment keine float/double, da ich dafür noch keinen Bedarf hatte.


    Beispiel:

    Code
    1. buffer = malloc(100+1);
    2. uint required = printFormatted(buffer, 100+1, "SEHR langer string\n");
    3. if (required > 100)
    4. {
    5. buffer = malloc(required+1);
    6. printFormatted(buffer, required+1, "SEHR langer string\n");
    7. }
  • [..]

    Beispiel:

    Code
    1. buffer = malloc(100+1);
    2. uint required = printFormatted(buffer, 100+1, "SEHR langer string\n");
    3. if (required > 100)
    4. {
    5. buffer = malloc(required+1);
    6. printFormatted(buffer, required+1, "SEHR langer string\n");
    7. }

    Sollte man bei

    Code
    1. buffer = malloc(required+1);

    nicht vorher mit free(buffer) den zu kleinen Buffer freigeben? Sonst haben wir doch ein Memory-Leak, oder?

  • Weiter an meiner Excel Terminplanungstabelle gearbeitet. Wer glaubt das BASIC V2 fehlerhaft und langsam ist, der hat noch nie mit VBA programmiert. :kaputt

    Wir nutzen sehr oft eine Fernsteuerung für Excel aus VB6 heraus.

    Das VB6 ist in Ordnung, aber das Excel ist manchmal absurd... "Zelle löschen" stellt man sich so einfach vor, Zelle auswählen und dann löschen oder einen Leerstring reinschreiben - AM ARSCH!

  • Wir nutzen sehr oft eine Fernsteuerung für Excel aus VB6 heraus.

    Das VB6 ist in Ordnung, aber das Excel ist manchmal absurd... "Zelle löschen" stellt man sich so einfach vor, Zelle auswählen und dann löschen oder einen Leerstring reinschreiben - AM ARSCH!

    Wie performant ist es? In meiner Firma habe ich ein Sheet für die Arbeitszeit, da muss ich einmal im Monat die Zeiten anpassen. Wenn ich da 5 Felder von einer Woche in die nächste Woche kopiere, dann denkt Excel locker 5 Minuten nach und ich frage mich ernsthaft was da so lange dauern soll.

    Bin froh dass ich mit Excel sonst nichts zu tun habe.

  • Da ist aber dann was anderes im Argen, zieht da irgendein VBA-Script hinterher?


    Das ist der Grund, warum ich Calc und Libre-Office wieder runtergeschmissen habe. Mit schöner Regelmässigkeit ist beim Kopieren einiger Zellen von einem Arbeitsblatt ins andere Calc total weggehängt (auch nach Minuten nicht zurückgekommen). Das macht man ein paar Mal mit, aber dann ist es auch gut.

  • Wie performant ist es? In meiner Firma habe ich ein Sheet für die Arbeitszeit, da muss ich einmal im Monat die Zeiten anpassen. Wenn ich da 5 Felder von einer Woche in die nächste Woche kopiere, dann denkt Excel locker 5 Minuten nach und ich frage mich ernsthaft was da so lange dauern soll.

    Mäßig...

    Bei uns geht es hauptsächlich um das Drucken von Packlisten, die der Kunde als Excel haben möchte, bisschen Recordsets durchlaufen, Zeilen zählen, Bereiche (und damit Layouts) kopieren, Zellen füllen.

    Gefühlt ist das so eine Sekunde je Teil, gefühlt ist Basic V2 jedenfalls deutlich schneller.

  • Ich wollte ja noch mein memset auch mit dem Blitter implementieren. Das hätte zwar den Nachteil das es nur mit Chip Mem geht, aber den Vorteil dass man z.B. den Blitter einen Bereich clearen lassen kann, während man schon andere Sachen vorbereitet. Da ich damit keine Erfahrung habe, habe ich stattdessen erstmal an meiner CPU Blit Routine weiter gearbeitet. Die ist zwar noch sehr experimentiell, aber man kann mit Einschränkungen zumindest schon mal Grafiken auf den Schir zaubern.

    So nach Bauchgefühl dachte ich dass die Funktion viel zu langsam ist, deshalb habe ich mir dann eine 16x16 Bitmap erstellt (was ja dann so ca. einem Font entspricht) und getestet. Damit bin ich auf ca. 1550 Zeichen pro Sekunden gekommen bei einem vierfarbigen Zeichen.

    Kann das allerdings nicht richtig einordnen, ob das dann schnell genug sein wird. Allerdings muss ich erstmal die Funktion fertig machen, so dass sie so funktioniert wie sie soll, und dann kann ich mir überlegen ob man sie schneller bekommt.

    Werde dann auch mal mit dem Blitter testen um zu schauen wie gross da der Unterschied ist.


    Dabei bin ich auf ein echt ntzliches Buch gestossen. Eigentlich habe ich ganz was anderes gesucht, und habe dann einen ganzen Haufen Bücher als PDF gefunden. Dabei habe ich auch mal da reingeschaut "Amiga Spiele Programmierung in Assembler" (https://archive.org/details/sp…ogrammierung-in-assembler) und habe bereits beim Durchblättern schon zwei Funktionenen gefunden die schon verwenden kann. Schade dass man das Buch scheinbar nirgends bekommt, das hätte ich gern im Original. :)


    https://archive.org/details/amigabooks

  • Die CPU und der Blitter können nicht gleichzeitig im ChipRam schreiben/lesen. Für das Löschen des Speichers ist eine Kombination aus Blitter und CPU das Beste. Ich rede hier vom 68000 Amiga. Als Buch kann ich das "Amiga Intern" empfehlen.

    Die können nicht beide auf das RAM gleichzeitig zugreifen, aber man kann trotzdem den Blitter starten und währenddessen was anderes tun, ohne das man snychron warten muss auf den Blitter. Die CPU ist dann halt langsamer weil sie weniger Zugriffe durch den DMA bekommt.

  • Gestern hab eich mein memset() per Blitter implementiert. Hat auf Anhieb funktioniert :thumbsup:. Dann habe ich eine Kontrolle eingebaut und gesehen dass die Funktion gar nichts gemacht. :pumpkin: Da ich dann schon zu müde war, wollte ich schlafen gehen und natürlich ist mir nach fünf Minuten eingefallen, woran es lag. Da ich wusste, dass es spät wird, wenn ich jetzt nochmal damit anfange, habe ich es erstmal sein gelassen.

    Heute habe ich das dann ausprobiert und damit hat es tatsächlich funktioniert. :thumbsup: Ich hatte nämlich einfach nur vergessen, den Blitter DMA einzuschalten. :D


    Die Ergebnisse finde ich recht interessant. Mein Test benutzt den Vertikal Blank Interrupt als Masseinheit. Bei einem PAL System sind das ja 50hz, als lasse ich das so lange laufen bis 50 VBIs passiert sind (also eine Sekunde) und dann gebe ich aus, wie oft ich es geschafft habe in der Zet meine Funktionen auszuführen.

    Wenn ich den Blitter für 10KB benutze, dann auf 328x, wenn ich das mit der CPU mache sind es nur 260x. Dann habe ich den Test erweitert und benutze 2x10KB Puffer. Ich start den Blitter und löschen den zweiten Bereich mit der CPU. Damit kome ich dann auf 248 Durchläufe, und habe noch ein wenig über weil ich trotzdem noch auf den Blitter warten muss.


    D.H. also, dass ich die doppelte Menge Speicher in fast der gleichen Zeit bearbeiten kann, was ja eine ganz gute Erkenntniss ist.

    D.H. wenn ich Tripple Buffering benutzen würde, dann würde ein Bildschirm gerade angezeigt, während der zweite gelöscht wird und ich am dritten für die Anzeige arbeite. Allerdings frage ich ich ob beim Amiga Tripple Buffering nicht etwas viel ist, wegen dem Speicher. Andererseits weiss ich noch nicht wie man bei Double Buffering am Besten dann die Aufgaben verteilt.

    Zumindest bekomme ich mit diesem Test schon ein wenig Gefühl dafür wie schnell die einzelnen Komponenten sind.


    Auf jeden Fall finde ich die Amiga Hardware echt geil zu Programmieren. Das meiste ist so einfach designed, dass man es echt Problemlos benutzen kann, ohne komplizierte Klimzüge machen zu müssen. Das einzige Lästige ist die Bitplanestruktur für die Bidlschirmanzeige. Ein Bitmap würde vieles vereinfachen, aber wenn ich mir überlege warum man das so gemacht hat, kann ich verstehen dass ein anderes Design auch viele Probleme erzeugt hätte.

  • Neues Update meiner Library ist jetzt im master: https://github.com/skeetor/amiga-utils/tree/develop


    * Einige Bugfixes, z.B. im Systemsave

    * memfill Ein Ersatz für memset welches bis zu 60% schneller ist (je nach Blockgrösse)

    * memfillBlit Ein memset welches auf 128k begrenzt ist, dafür aber den Blitter benutzt, so das man parallel dazu schon weiter arbeiten kann.


    Ausserdem einige Helfer um die Kommandozeilenparameter zu prüfen und auszulesen, indem man definiert welche Parameter erlaubt sind und eventuelle Limits (z.B. Mandatory, Prüfung Anzahl der Argument, etc.).

  • Hab Heute am BMC64 Sideboard weiter gearbeitet (5, Taster und 4 Analogwerte Paddles via USB HID und Atmega32u4 )


    Die Implementation war viel Spaß bis jetzt, die Prämisse dabei:

    Möglichst schnell AD-Wandeln, möglichst wenig Overhead USB-seitig und trotzdem maximal 5 us Verzögerung (ginge schneller) vor dem HID Update.


    Trockentest sieht gut aus, die Tage dann am lebendem Objekt testen.

    Freu mich schon auf Arkanoid mit Paddles