PathWarp To Path bzw. Text zu Bezierkurve biegen

  • Ich hab hier eine UDF für euch, mit der man Text auf eine Kurve projizieren kann.

    Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.

    Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.

    Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.

    Die Idee dazu stammt von hier: http://www.planetclegg.com/projects/WarpingTextToSplines.html

    Im Anhang befindet sich die UDF incl. Beispiele
    Die UDF ist noch Beta, deshalb fehlen noch die Funktionsbeschreibungen; Ich hoffe aber, dass die Beispiele trotzdem zu verstehen sind ;)


    Viel Spaß beim experimentieren...
    Ach ja - läuft nur unter X86.

    E

  • FETT! 8o

    Example 7 gefällt mir am besten!

    Wäre die Laufzeit ohne ASM zu langsam? Interessant wäre auch der Maschinencode in ASM Code dargestellt. ;)

    Gruß,
    UEZ :thumbup:

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hier ein kleines Intro ala AAAAAAAMMMMMMMMIIIIIIIIIIIGGGGGGGGGAAAAAAAA! :rock:

    Source Code: http://pastebin.com/U24ACRAr

    Basiert auf Example 7.

    Der ASM Teil läuft anscheinend nur auf Win7 oder höheren Betriebssystemen (bitte mal testen)! Liegt daran, dass DEP eingeschaltet ist. Sollte jetzt ab WinXP funzen!

    Gruß,
    UEZ

  • Zitat von UEZ

    Der ASM Teil läuft anscheinend nur auf Win7 oder höheren Betriebssystemen (bitte mal testen)!


    Läuft alles ganz normal :D (Win XP SP 2)

    Um Missverständnisse zu vermeiden, mein Name rührt vom Sternenbild und nicht vom Shop her :D


    Rainbow Dash :rock:

    "Das, wobei unsere Berechnungen versagen, nennen wir Zufall." (Albert Einstein)

  • Sehr cooles Script UEZ! :rock:
    Das bringt mich auf eine Idee - gleich mal ausprobieren ;)

    Läuft bei mir übrigens auf WinXP und Win7 ohne Probleme

    Mit reinem AutoIt-Code wird z.B. Example_7 nur alle 4 Sekunden geupdated.
    Evtl. könnte man den Code auf die doppelte Geschwindigkeit optimieren, aber wirklich flüssig gehts nur mit ASM


    Im Anhang der ASM-Code für die Interessierten

    E

  • Hi,

    UEZ,
    sehr sehr nice :thumbup:

    eukalyptus
    DAS nenne ich mal ein schickes Stück Code!!! :rock: *wieso gibts eigentlich keinen "verbeug"-smilie*
    Habe mir den ASM-Teil natürlich disassembliert und mal drübergeschaut, weil die Funktion _PW_Warp() doch relativ lange läuft. //EDIT// uups, meinen Text viel zu lange editiert und posten verpennt, der ASM-Code ist schon da! Btw, auch sehr schön kommentiert!

    Versuche mal, den Teil im Stack, in dem du die XMM-Register speicherst, an einer 16-Bitadresse zu alignen. Das hat den Vorteil, dass du diese Adressen per MOVDQA statt MOVDQU lesen/schreiben kannst.

    Dann habe ich festgestellt, dass du den größten Vorteil bei SSE, nämlich das parallele Ausführen von Code, nicht genug nutzt.
    Ja, das ist auch teilweise schwer, Abhängigkeiten bleiben halt nicht aus.
    bsp:

    Zitat

    movdqa xmm0,xmm1 ;xmm0 bearbeiten
    mulps xmm0,xmm3 ;xmm0 stall, wartet darauf, dass der vorige Befehl abgearbeitet wurde
    movdqa xmm4,xmm5 ;andere Register bearbeiten


    schneller:

    Zitat

    movdqa xmm0,xmm1 ;xmm0 bearbeiten
    movdqa xmm4,xmm5 ;läuft in der instruction Pipeline parallel zur zeile vorher, da keine dependencies
    mulps xmm0,xmm3 ;xmm0 muss nicht auf den vorigen Befehl warten, schneller


    das bringt idR dann etwas, wenn diese Zeilen im inner loop sehr häufig durchlaufen werden.

    Wenn wir schon beim Inner Loop sind, Code Aligning ist sehr wichtig!
    Vor die Loops gehört ein "align 16" (habe ich jetzt nicht geschaut, ob du das gemacht hast, finde aber auch keinen Hinweis, dass du es gemacht hast^^)

    Auch die AutoIt-Structs, aus denen du Daten liest/schreibst gehören 16-Byte-aligned!Da das align16 innerhalb von dllstructcreate nicht zuverlassig funktioniert, habe ich mir eine Funktion dafür geschrieben

    Spoiler anzeigen
    [autoit]

    Func _dllstructcreate16($struct) ;align auf 16-byte adresse
    $temp = DllStructCreate($struct)
    $tempsize = DllStructGetSize($temp) + 16
    $temp = 0
    $mem = _MemGlobalAlloc($tempsize + 16, BitOR($GMEM_FIXED, $GMEM_ZEROINIT)) ;pointer auf speicher
    $a = Mod(Number($mem), 16) ;rest div 16 adresse = offset
    Return DllStructCreate($struct, (Number($mem) - $a + 16)) ;auf 16 alingned pointer
    EndFunc ;==>_dllstructcreate16

    [/autoit]


    Wenn du die Möglichkeit hast, dann bau die Struct direkt so, dass du immer 16-Byte Blöcke holen kannst.
    Wenn du 2 Structs mit Datenpaaren hast (Erste in Struct1, Partner in Struct2) dann schreib statt
    Struct1=X1,X2,X3,X4,X5...
    Struct2=Y1,Y2,Y3,Y4....
    eine Struct mit
    Struct=X1,Y1,X2,Y2,X3,Y3......
    das reduziert massiv die Cache-Misses beim lesen!
    Apropos....per Prefetch lässt sich der Cache mit Daten "vorladen".

    Das profilen des Codes bzw. Ausstoppen der Laufzeiten mache ich mit einem simplen RDTSC am Beginn und Ende des Loops....


    Aber ansonsten absolut super! :thumbup:
    Ich wäre echt mal gespannt, was ein C-Compiler aus dem Code gemacht hätte, vielleicht erbarmt sich ja mal jemand und compiled den Algorithmus mit /SSE-Flag...

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (1. Mai 2013 um 19:04)

  • eukalyptus: der Dank gehört dir! Die paar Zeilen Code von mir sind da nicht erwähnenswert! Dein Auffassungsvermögen ist schon echt irre! :thumbup:

    Andy: den "Verbeuge" Smiley gibt's bestimmt irgendwo, aber der hier tut's auch: [Blockierte Grafik: http://www.smileygarden.de/smilie/Sonstige/bowdown.gif]

    @Pee: unter http://www.smileygarden.de gibt's tonnenweise Smileys. Wie wäre's mit ein paar Neuen?

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • "Wenn ich mal groß bin will ich genau so sein wie die PU's" :D
    Echt klasse was ihr immer aus AutoIt raushaut und umsetzt! (Naja, auch wenns bischen ASM gecheatet ist ^^)

    eukalyptus:
    Echt tolle UDF! :)
    Ich finde keine Worte dafür. :D

    UEZ:
    Super was du damit gezaubert hast. ^^
    Auch hier finde ich keine Worte! :P

    Bitte macht weiter so!
    Ich selber versuche auch aus euren Codes zu lernen.
    Aber manchmal fällts dann doch schwer wie hier. ^^

    LG. Make :)

  • Hi,

    Zitat

    Echt klasse was ihr immer aus AutoIt raushaut und umsetzt! (Naja, auch wenns bischen ASM gecheatet ist )


    "Gecheatet" würde ich das nicht nennen, lediglich das Erkennen von Defiziten und deren Umgehung. An ASM ist in keinster Weise etwas irregulär oder gar unmoralisch oder betrügerisch!
    Mal angenommen, das Script würde 1:1 nach C++ übersetzt, so würde eine ähnliche Framerate entstehen. Dieses Script in ein beliebiges C++-Forum gestellt und nach Hilfe zur Beschleunigung gefragt, wäre ich mal SEHR gespannt auf die Beiträge der qualifizierten User.
    Da sämtliche GDI+-Funktionen nicht zu beschleunigen sind, bleibt also nur noch der Rest....also das, was eukalyptus in ASM-Code umgesetzt hat, und das sind Berechnungen.
    Und die zu optimieren, dafür braucht es das KnowHow, und nicht einen "schnellen" Compiler! Letztendlich würden einige Handvoll C++-Cracks den vom Compiler fabrizierten Code profilen und disasseblieren, und irgendwann käme einer daher und würde die letzten 3-4 FPS über einige Zeilen Inline-ASM rausholen. Dann wäre er kein "Cheater", sondern ein von allen vielbeachteter Programmierer!
    Wenn jemand dasselbe in AutoIt macht, ist er ein "Cheater"?

    Und für die Idee und deren Umsetzung (s.UEZ´s viele tolle Beispiele) braucht es viel Phantasie und noch mehr Gehirnschmalz....beides etwas, was ich 99,9% aller c&p-"Cheater" abspreche!


    UEZ,
    für eukalyptus reicht ein einzelner smilie nicht, ich hatte eher an so etwas gedacht: [Blockierte Grafik: http://sarpbc-forum.birk-gollin.de/images/smileys/betengros.gif]

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (1. Mai 2013 um 19:15)

  • Fuu :x
    So meinte ich das doch gar nicht ^^
    >> Es bezog sich dabei auf meine Aussage: "Echt klasse was ihr immer aus AutoIt raushaut und umsetzt!"

    Aber weil Assembler nun mal nicht AutoIt ist (Syntaxmäßig / Geschwindigkeitsmäßig) habe ich den Begriff "Gecheatet" verwendet um damit auszudrücken dass die Berechnungen eben nicht in AutoIt stattfinden. Ich wollte damit keineswegs damit Assembler niedermachen oder gar eine Person.

    Hab mich nur (wie so oft) falsch ausgedrückt. ^^

  • @Make-Grafik,
    war mir doch klar... ;)

  • Erstmal Danke für die Lorbeeren!

    Auch die AutoIt-Structs, aus denen du Daten liest/schreibst gehören 16-Byte-aligned!


    Mit dem Alignen hatte ich in der Vergangenheit immer wieder mal Probleme.
    Und zwar funktioniert der Code problemlos, solange der ASM-Code "live" kompiliert wird.
    Sobald man aber den kompilierten ByteCode benutzt, stürzt das Script plötzlich hin und wieder ab.
    Da ich dieses Problem bisher nicht lösen konnte, verwende ich immer movdqu, auch wenn es langsamer ist.
    Und das betrifft leider auch die Speicherstelle im Stack!

    Zuerst dachte ich, dass ich nur den "CodeBuffer" alignen müsste, aber auch das hat nicht geholfen...


    Wenn du die Möglichkeit hast, dann bau die Struct direkt so, dass du immer 16-Byte Blöcke holen kannst


    Der Aufbau hängt in diesem Fall von GDIPlus ab; ich lese und schreibe eben in dem Format, damit ich die Daten dann direkt an GDIPlus weitergeben kann.

    Im Großen und Ganzen bin ich ja mit meiner Leistung zufrieden.
    Ich benötige ja derzeit schon 130% meiner Gehirnleistung um überhaupt die Werte der einzelnen Register im Auge zu behalten. ^^
    Für weitere Optimierungsschritte hab ich z.Z leider keinen Slot mehr frei :D


    E

  • Wie gesagt hängt es an DEP, ob DEP aktiviert ist oder nicht. Das Problem ist, dass der ASM Teil direkt in den Speicher schreibt und ausführt; DEP verhindert dies.

    Einfach mal DEP einschalten und eines der Beispiele starten. Das Intro sollte davon nicht betroffen sein. ;)

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯