Battle: Autoit vs. FreeBasic - Runde 1+2+3

  • Alles, was mit aufwendigen (!) "Berechnungen" zu tun hat, bzw. mit langen/häufigen Schleifenaufrufen, läuft in FB wesentlich schneller.

    This

    Imho ist es wesentlich wichtiger/sinnvoller, einen geeigneten/schnellen Algorithmus für die Problemlösung zu finden.

    This²

    Ein "langsamer" Algorithmus wird immer "langsam" bleiben, auch wenn er auf eine schnellere Hardware/Programmiersprache portiert wird.

    Erstrecht this!

    Die Compiler werden zwar immer besser, doch handoptimierter Code ist bei aufwendigen Aufgaben immer noch einen Tick schneller.

    Hier muss ich ganz kurz einen Einwand geben / deine Aussage präzisieren. Wenn der Algorithmus optimiert wurde: Ja, das deckt sich aber auch direkt mit der Aussage darüber, dass ein beschissener Algorithmus immer noch beschissen bleibt, egal wie viele Operationen in einer Sekunde wir auch ausführen können.
    Der "handoptimierte" Code kann sich lediglich auf die, unmittelbar darüber erwähnten, ASM Sequenzen beziehen. Du wirst, wenn du nicht mit der Architektur vertraut bist, niemals einen besser optimierten Code, als dein Compiler ihn schreibt, schreiben können. Niemals..... Es sei denn du schreibst so äußerst beschissenen Code, dann hast du aber auch keinen Plan von ASM, womit sich das Gott sei Dank aufhebt :P

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Ich habe jetzt den Code angepasst, sodass nur im gleichen Pfad geschaut wird, d.h. sollte jetzt funzen.

    Bitte mal testen!

    Funktioniert auf win10 x64 mit 7 FPS. Afair hast du aber schon einmal ein ähnliches mit AutoIt geschriebenes Skript eingestellt. Und da ich dem Source entnehme, das du zeitkritische Aufgaben mit Inlineassembler löst, sollte der Nachteil von AutoIt nicht so stark zum tragen kommen.

    mfg (auto)Bert

  • Afair hast du aber schon einmal ein ähnliches mit AutoIt geschriebenes Skript eingestellt.

    Nun ja, definiere "ähnliches". Über 1000 Pixel nativ in AutoIt macht keinen Sinn, es sei denn, du codest mit Inline Assembler, das aber erst mal gelernt werden will.

    7 FPS ist nicht besonders schnell. Da nehme ich an, dass deine CPU nicht die Schnellste ist.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Und da ich dem Source entnehme, das du zeitkritische Aufgaben mit Inlineassembler löst,

    Hihi, DER hat gesessen :thumbup:
    Der Inline-ASM-Code berücksichtigt genau das, was ich bereits sagte, ersetzen von "langsamen" (API-)Funktionen durch "schnellere".
    Was dann die Frage erlaubt, wieso nicht gleich die komplette "langsame" Schleife (der Compiler kanns halt nicht besser...) in "schnell" gecodet wird... :theke:


    Du wirst, wenn du nicht mit der Architektur vertraut bist, niemals einen besser optimierten Code, als dein Compiler ihn schreibt, schreiben können. Niemals....

    Ich bin mir nicht ganz sicher ob ich dich jetzt verstanden, und/oder ob ich mich vielleicht ungeschickt ausgedrückt habe. Daher noch mal deutlich:
    JA, für "Otto-Normal-Programmierer" bleibt der vom Compiler erstellte Code "der schnellste/beste".
    Und JA, für 99,9% von rechenintensivem, von Compilern erstelltem Code gibt es die schnellere Version in handoptimiertem ASM. Das hängt einfach mit der Art und Weise zusammen, wie der Compilerbauer seine Arbeit gemacht hat. "Klassisch" reserviert ein Compiler Speicher für verwendete Variablen (meist auf dem Stack). Da idR ein "dummer" Compiler (und das sind die allermeisten) Code nicht im Vorfeld auf die Verwendung bspw. dieser Variablen analysiert, "merkt" er auch nicht, dass statt dieses Speichers die wesentlich schnelleren Prozessorregister verwendet werden könnten.
    Bei der Verwendung von SSE-Schaltern und anschließender Analyse des Compilates kommt dann bspw. heraus, dass zwar einzelne SSE-Register verwendet werden, aber die damit möglichen SIMD-Berechnungen überhaupt nicht oder nur rudimentär verwendet werden. Idr. "sieht" man dem Compilat schon an, ob es beschleunigt werden kann.
    In den gängigen ASM-Foren ist man sich durchaus bewußt, dass die Compiler (glücklicherweise) immer besser werden, allerdings ist genauso klar, dass ein ein guter ASM-Programmierer (glücklicherweise) immer noch den einen oder anderen Hasen aus dem Hut zaubern kann....
    Aber genau das ist doch der Punkt! Kein Compilerbauer hätte einen Anreiz, besseren Code zu schreiben, wenn das für die jeweilige Architektur erstellte Compilat schon optimal wäre. Die handoptimierten ASM-Bibliotheken, egal für welche Architektur, machen es doch vor!
    Die Frage ist dabei, inwieweit sich die "Handoptimierung" überhaupt lohnt. Wenn ich sehe, dass bspw. sehr grafikintesive Programme mit extrem gut zu parallelisierbaren Filtern mit Techniken aus dem vorigen Jahrhundert arbeiten, aber kein einziger Anwender sich an der "Wartezeit" stört, weil auf dem Markt keine einzige Alternative besteht, dann wird klar wie der Hase läuft: nur wenn "Druck" seitens Wettbewerb auf das Produkt ausgeübt wird, entscheidet sich der Entwickler dazu "schnellere" Techniken einzusetzen.

    Ja, das deckt sich aber auch direkt mit der Aussage darüber, dass ein beschissener Algorithmus immer noch beschissen bleibt, egal wie viele Operationen in einer Sekunde wir auch ausführen können.

    Trifft somit den Nagel auf den Kopf! Wenn der "beschissene" Code aber nur Millisekunden zur Ausführung benötigt, was dem Programmierer idR völlig egal ist, juckt das NIEMANDEN! Nun nimmt jemand anderer diesen Code, schreibt ihn in eine Funktion und ruft diese Funktion auch noch Millionen Male auf....mit dem Ergebnis dass extrem lange Wartezeiten entstehen. Solange auch das NIEMANDEN juckt, ist alles schick!
    Wenn aber ein "richtiger" Programmierer den Hebel ansetzt und den Algorithmus optimiert und danach noch ggf. mit den Compilerschaltern so herumspielt, dass letztendlich eine x-fache Beschleunigung herauskommt, fängt das vorwurfsvolle Gequieke der Gemeinde an: "DAS müsste eigentlich der Compiler von alleine können...."
    Und so analysieren und optimieren die führenden Compiler mittlerweile den hingerotzten Source-Code, stellen ihn um und beheben die Defizite der "Otto-Normal-Programmierer", welche sich mit den von dir angesprochenen Architekturen absolut nicht mehr auskennen, und machen letztendlich "aus Scheiße Gold". Und genau diese "Otto-Normal-Programmierer" wundern sich dann, wenn sie nur noch einen Knopp und einen Klicker verdienen, da sie von x-beliebigen "Developern" weltweit ersetzt werden können....
    Wer sich auf das KnowHow von anderen verlassen muss, ist schnell selbst verlassen!

  • Ich erinnere mich an ein Script (mit Dali als Bild) bei dem das Gesicht sich verändert. Es handelt sich um autoit.de/index.php/Attachment/83460-Wave-v1-3-2-au3/ in dem ich spaßhalber Dali (aus CosinusBrothers) eingesetzt habe, läuft bei mir mit 2 FPS.

    Da werden nur die Zeilen versetzt dargestellt und in diesem FB Beispiel jedes einzelne Pixel. Je mehr Pixel desto langsamer.

    Aber ja, ähnlich sieht es aus. ;)

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ich habe auch nur 5-7 FPS :huh:
    Wird dann auf einen i7 6950x und eine GTX 1080 rauslaufen, damit 25FPS in Reichweite sind :ironie:

  • Auf meinem Schlepptop läuft's mit ca. 20 FPS.

    CPU: Intel Core i5-4300U
    Gfx: Intel HD Graphics 4400

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Und JA, für 99,9% von rechenintensivem, von Compilern erstelltem Code gibt es die schnellere Version in handoptimiertem ASM.

    Genau das meine ich anders herum: Nein, gibt es nicht.

    Da idR ein "dummer" Compiler (und das sind die allermeisten) Code nicht im Vorfeld auf die Verwendung bspw. dieser Variablen analysiert, "merkt" er auch nicht, dass statt dieses Speichers die wesentlich schnelleren Prozessorregister verwendet werden könnten.

    Widerspreche ebenfalls: Der Code wird heutzutage akribisch vom Compiler untersucht, bevor er übersetzt wird.

    möglichen SIMD-Berechnungen überhaupt nicht oder nur rudimentär verwendet werden

    Und genau hier haben wir doch den Fehler! Du kannst bereits SIMD Befehle von Hause aus nutzen, das macht sogar @UEZ manchmal, wenn ich richtig sah, da er die MMX Technologie benutzt.
    Das kannst du jetzt nicht auf den Compiler abschieben, dass der Programmierer zu dämlich ist seine Möglichkeiten auszuschöpfen. Ein Compiler holt schon viel aus dem dummen Code des Anwenders heraus.
    Angenommen du schreibst zu 99.9% optimierten Code in C, lässt ihn Compilieren und schreibst danach für das gleiche Problem 99.9% optimierten Code in ASM: Du dürftest genau 0% Geschwindigkeitsunterschied haben. (da ich mich damit sehr weit aus dem Fenster lehne, sage ich mal ca 0%, da es marginal sein dürfte).

    Und genau das wollte ich mit meiner Aussage vorhin sagen: Beschissen bleibt beschissen.
    Sicher schreibt ein guter ASM Programmierer ein Scheiß C Programm in ASM besser, wenn er selbiges aber in C schreiben würde, würde er es erst gar nicht so beschissen schreiben und demnach auch auf etwa Gleiche Geschwindigkeit kommen.

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Du kannst bereits SIMD Befehle von Hause aus nutzen, das macht sogar @UEZ manchmal, wenn ich richtig sah, da er die MMX Technologie benutzt.

    In diesem Beispiel "GDI Liquid Pixels" bringen die manuellen Sin/Cos Assembler Versionen ca. 25% mehr Leistung, aber dafür auf Kosten der Genauigkeit, ist aber für dieses Beispiel irrelevant.
    Für hoch kritische Anwendungen, z.B. Raumfahrt, könnte es zu Problemen führen, dass die Werte zu "ungenau" sind.

    Ich habe leider nicht das Wissen bezüglich Compilerbau, so dass ich nicht qualitativ bewerten kann, ob der FB Compiler seinen Arbeit gut erledigt, aber da ist für spezielle Bereiche, wie grafische Verarbeitung, noch Luft nach oben.

    Wie bereits erwähnt, müssten man den gleichen Codeaufbau mit verschiedenen Programmiersprachen vergleichen, was der Compiler da noch heraus kitzelt.
    Der Vergleich mit AutoIt war da nur Just for Fun und eher unfair. Man vergleicht ja auch nicht ein Kleinwagen mit einem Sportwagen bezüglich Geschwindigkeit, z.B. Corsa vs. Ferrari.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Genau das meine ich anders herum: Nein, gibt es nicht.

    Dann treib dich in einschlägigen Foren rum, da wirst du eines besseren belehrt...incl. Beispielen.

    Widerspreche ebenfalls: Der Code wird heutzutage akribisch vom Compiler untersucht, bevor er übersetzt wird.

    Selbst der Intel-Compiler, welcher SEHR guten Code fabriziert, muss sich immer noch an das Compiler-Procedere halten, und das macht er auch!
    Allerdings hat er auch mit SSE/SIMD seine (zugegeben marginalen) Schwierigkeiten, was auch völlig normal ist, denn ein Programmierer setzt die Befehle bei SIMD "von hinten nach vorne" um, da hat der Compiler schlechte Karten, denn zzt. kann der nur "von vorne nach hinten". Ich gehe davon aus, in der nächsten Version wird da noch einiges gehen.
    Und wir reden hier von einem Compiler, der in der 2000 bis 3000€-Klasse spielt. Was er auch wert ist, nicht wegen dem (fast kostenlosen) Compiler, sondern den wirklich geilen Programmen, die eine komplette Infrastruktur bereitstellen. Wer einmal seine rechenintensiven Programme mittels Profiler verbessert hat, möchte solch ein Programm nicht mehr missen!
    Und auch dieser Compiler versucht erst in der neuesten Version selbsständig die vom (ahnungslosen) Programmierer eingehackten AoS in SoA zu "transferieren"

    Zitat von INTEL-Paper

    If possible, it is desirable to reorganize data into a Stucture of Arrays (SoA) organization. Unfortunately, for real world applications this may prove to be a non-trivial amount of effort. However, the benefits of doing such a transformation may be quite significant.

    Auf deutsch übersetzt steht da, wenn der Programmierer Ahnung von dem hätte was er da tut, würde er solch einen Mist garnicht erst machen...


    Bei den hier vorgestellten Basic-Compilern (und auch anderen X86-Compilern) brauchst du mit "akribisch Code untersuchen" nicht kommen, genau wie bei den meisten C(++)-Compilern. Die werden ALLE von halbwegs fähigen ASM-Programmierern geschlagen.
    Wegen "nichts" haben nicht sämtliche Compilerhersteller Intrinsics() implementiert. Diese ermöglichen auch "Otto-Normal-Programmierer" die Verwendung von ASM-Code, so er denn weiß, was er da tut....

    Schreib eine rechenintensive Funktion, nudel diese durch einen beliebigen Compiler und schau dir das Compilat an, wenn dort in jeder 3.Zeile irgendein Speicherzugriff stattfindet, kannst du schon einpacken.

    //EDIT
    https://groups.google.com/forum/#!topic/…x86/TtF6aaS8MeQ
    Acker das mal komplett durch, damit du weißt, was abgeht :D

  • Auf deutsch übersetzt steht da, wenn der Programmierer Ahnung von dem hätte was er da tut, würde er solch einen Mist garnicht erst machen...

    Und genau das ist der Kern der ganzen Geschichte. Dem widerspreche ich ja auch nicht.

    Schreib eine rechenintensive Funktion, nudel diese durch einen beliebigen Compiler und schau dir das Compilat an, wenn dort in jeder 3.Zeile irgendein Speicherzugriff stattfindet, kannst du schon einpacken.

    Also wir gehen mal davon aus, dass fähiger, besagter ASM Programmierer, besser in ASM fährt als der kompilierte Code. Ausgehend von der Aussage mit den Registern: In C kannst du direkt die Register ansprechen, ebenso in C++, das ist also erstmal noch kein Beinbruch.

    Ich will dir absolut nicht absprechen, dass ein fähiger ASM Programmierer besseren Compiler Code liefert, ich kann aber nicht damit mit gehen, dass vorher guter Code im Compilat immer noch riesige Differenzen zum reinen ASM Code hat.
    Andererseits, nimm das bitte nicht persönlich, denke ich bei "fähigem ASM Programmierer" eher an dich, was vermutlich noch weit entfernt von dem ist, worüber du redest. Ich traue dir durchaus sehr viel in dahingehend zu, aber vermutlich hast auch du nicht die Ahnung vom Kern der Architekturen, von den Leuten von denen du redest. Und da wird wohl mein Denkfehler liegen ^^ , weshalb ich mich den Aussagen gegenüber weigere :D

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Ausgehend von der Aussage mit den Registern: In C kannst du direkt die Register ansprechen

    KANNST...du hast es erfasst...KANNST..., das ist genau wie alles andere was man eben KÖNNEN muss!
    Wenn sich Profis, die sich jahrelang mit ggf. diversen Compilern auseinander gesetzt haben, Code analysiert, ihre Algorithmen verfeinert/angepasst haben, die Wirkung ihrer Compilerschalter kennen und "natürlich" auch die Hardware kennen und WISSEN (durch lesen des erstellten ASM-Codes) was der Compiler aus ihrem Getipper macht, dann ist das etwas völlig anderes wie ein "Programmierer" der irgendwelchen HLL-Code in eine IDE kloppt, auf F5 drückt und dann behauptet, ein Compiler würde daraus den schnellsten/besten/kürzesten Code bauen (welcher keinesfalls zu verbessern ist)!

    ich kann aber nicht damit mit gehen, dass vorher guter Code im Compilat immer noch riesige Differenzen zum reinen ASM Code hat.

    Hat er auch nicht, hab ich auch nie behauptet. Was ich behaupte ist, dass der Compiler (noch nicht) aus einer unzureichenden Implementation/Algorithmus das "Optimum" rausholt. Woher soll er auch wissen was das Ziel des Programmierers ist? Der Compiler nudelt stur seinen Quellcode durch, optimiert auf Teufel komm raus, und letztendlich muss er aufgeben und das abliefern, was er als schnellstes/bestes/kleinstes betrachtet!

    Guck mal auf die oben geposteten "Benchmarks/FPS", da wird sonnenklar, dass das Compilat "pro Intel" erstellt wurde. Ich denke mal, sicherlich nicht mit Absicht :D Wenn du aber nur einen Prozessor/Prozessorfamilie hast um auf diesen zu entwickeln, dann optimierst du logischerweise auch dafür!
    Vielleicht ist aber auch nur zufällig eine bestimmte Sequenz an Code von Intel-Prozessoren schneller zu verarbeiten, ggf. nur einige Takte, im Endeffekt macht das bei gleichem Code auf der Maschine mit gleichem Takt einen Unterschied von 20-30%, vielleicht in ungünstigen Fällen noch wesentlich mehr!
    Ich hatte in den ASM-Threads schon davon berichtet, dass ich bei Messungen von Codesequenzen 50 Takte erwartet hatte, die Hardware aber durch Pipelining und andere "optimierende" Schweinereien daraus ca. 2000Takte machte. In einem Loop mit Millionen Durchläufen ist das der Supergau! Und genau DAS meine ich! Wenn du dann nicht merkst "da stimmt was nicht", dann läuft etwas gewaltig schief! Einfach nur davon auszugehen, dass der Compiler aus Sch*** Gold macht, funktioniert nicht!

    Ich wäre übrigens dafür, die verschachtelten Schleifen mit den Berechnungen auch mal bei anderen Compilern und Sprachen durchlaufen zu lassen, dann hätte man mal Vergleiche. Ich sage jetzt einfach mal Unterschiede in der Laufzeit von 100% voraus...also halb/doppelt so schnell. Für die gleiche Schleife. Und dann noch auf unterschiedlicher Hardware laufen lassen. Das ist übrigens in div. ASM-Foren "Standard", also das benchen eigener Implementierungen auf div. Maschinen. Das kenne ich auch aus einigen C-Foren, allerdings "optimiert" man dort für den Compiler, d.h. man schaut, aus welchem C-Code der Compiler den schnellsten ASM-Code bastelt 8)

    denke ich bei "fähigem ASM Programmierer" eher an dich,

    Mit Sicherheit bin ich nicht "fähig" im Sinne von programmieren....

  • Mit Sicherheit bin ich nicht "fähig" im Sinne von programmieren....

    Na, mach dich nicht klein. Ich schätze dich schon sehr fähig ein :)

    Wenn sich Profis

    Wir drehen ums im Kreis :P genau darauf wollte ich hinaus :D

    Ich hatte in den ASM-Threads schon davon berichtet, dass ich bei Messungen von Codesequenzen 50 Takte erwartet hatte, die Hardware aber durch Pipelining und andere "optimierende" Schweinereien daraus ca. 2000Takte machte. In einem Loop mit Millionen Durchläufen ist das der Supergau! Und genau DAS meine ich!

    Hast du mal einen Link parat? Würde mich interessieren das mal zu sehen.

    Ich wäre übrigens dafür, die verschachtelten Schleifen mit den Berechnungen auch mal bei anderen Compilern und Sprachen durchlaufen zu lassen, dann hätte man mal Vergleiche. Ich sage jetzt einfach mal Unterschiede in der Laufzeit von 100% voraus...also halb/doppelt so schnell.

    Du meinst anstelle von in FreeBasic? Ist denn hier bis Dato mal ein anderer BASIC Compiler getestet worden? Das wäre ja auch mal interessant zu sehen. Vergleich: GNU/GCC vs MS C Compiler hatte mal eben eine Differenz um... oh Gott, ich weiß den Timestamp nicht mehr wo ich nachschauen müsste, aber das war so ohne Probleme der Faktor 0.25 :D (GNU/GCC war schneller)

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Hast du mal einen Link parat? Würde mich interessieren das mal zu sehen.

    Geschwindigkeitsvergleich C, Basic, Pascal Unerwartetes Ergebnis?!
    Übrigens war FreeBasic bzw. Vergleich AutoIt/Compilersprachen schon immer Thema :D

  • ...und wieder mal wird auch bei "aufwendiger" Grafik klar, wieviel schneller die uralten GDI- gegenüber den "plus"-Funktionen sind ;(
    Bei AutoIt fällt der Unterschied garnicht auf, bei FB ist bei mir die GDI-Version ca. 5-6x schneller als GDI+ X/

    Abgesehen davon habe ich mir natürlich den erzeugten ASM-Code angeschaut :D
    Der "klassisch" aufgebaute Compiler nutzt exzessiv (6KB) den Stack zum Zwischenschenspeichern der Variablen, JEDER der FPU-Befehle (SSE hat deshalb auch keinerlei Vorteile) greift statt auf innerhalb der FPU speicherbaren Werte/Konstanten auf das RAM zu....
    Ich bin ziemlich sicher, dass mindestens noch ein Faktor 5-10 in der Geschwindigkeit der Berechnung machbar wäre, würde man die FPU-Sequenz in Assembler handcoden....von SSE mit 4 gleichzeitig berechenbaren Arrayinhalten garnicht zu reden. Die Compilereinstellung zur Verwendung von SSE bringt übrigens keinen Vorteil, die "schnelleren" Befehle werden gänzlich von unproduktiven Zugriffen auf den Speicher ausgebremst :thumbdown:

    Beispielsweise kann

    Code
    ringf(r)     = posx + Cos(t) * multiplier
    			ringf(r + 1) = posy + Sin(t) * multiplier
    			ringf(r + 2) = posx + Cos(t + tstep) * multiplier
    			ringf(r + 3) = posy + Sin(t + tstep) * multiplier

    per SSE in einem Rutsch berechnet werden!
    Mal abgesehen davon, dass sämtliche Konstanten in den Registern statt im Speicher gehalten werden können und somit auch damit schneller gerechnet werden kann.


    Gerade dieser Code ist ein Beispiel dafür, dass "Compiler" auch nicht zaubern können 8o . "Klassisch" aufgestellte schon mal garnicht...
    Ich würde sonstwas dafür geben, mal zu sehen, was einer den modernen (Intel) Compiler aus dem Quellcode macht...
    Vielleicht hat ja jemand Lust, den Quellcode nach C(++) zu übertragen und zu testen?!


    Große Performancesprünge erwarte ich damit übrigens nicht, die FPS werden definitiv durch GDI/GDI+ begrenzt und nicht durch die Handvoll Berechnungen 8)

  • Auf der Windows API Index Seite wird uns ja nahegelegt:

    Zitat von msdn

    Deprecated or legacy APIs
    The following are technologies and APIs that are outdated or have been replaced or deprecated from the Windows client and server operating systems.

    - Graphics Device Interface (GDI): Use Direct2D instead.
    - GDI+: Use Direct2D instead.


    Habt ihr das mal mit Direct2D probiert?


    Was man aber noch machen kann um es ein bisschen zu beschleunigen, ist neben LoadLibrary auch GetModuleHandle und GetProcAdress zu benutzen, um die ganzen Funktionen ein bisschen schneller aufrufen zu können.

    2 Mal editiert, zuletzt von kaesereibe (22. September 2016 um 08:14)