Entwickler-Ecke
Algorithmen, Optimierung und Assembler - delphi asm tutorial
elundril - Mi 30.01.08 16:40
Titel: delphi asm tutorial
Hallo,
ich interessiere mich seit längerem für diese ASM funktion in Delphi. Ich denke mir immer: "Manches müsste doch mit assambler schneller gehen, oder?" und jetzt such ich tutorials wie man solche assamblercodes programmieren kann. könnt ihr mir ein paar links geben??
lg elundril
Moderiert von
Christian S.: Topic aus Sonstiges (Delphi) verschoben am Mi 30.01.2008 um 15:47
BenBE - Mi 30.01.08 17:14
Hab da zu hause in meine Doku-Sammlung ne CHM rumliegen, wo viele Dinge dazu erklärt werden (als Ref), ... da ich aber derzeit nicht zuhause bin, reich ich das bei Gelegenheit nach ...
white-desert - Do 31.01.08 10:13
BenBE hat folgendes geschrieben: |
Hab da zu hause in meine Doku-Sammlung ne CHM rumliegen, |
wuerde mich auch interessierten :-)
Lossy eX - Do 31.01.08 11:42
Gerade eben beim Überfliefen des Tutorials auf der DP im Abschnitt "3.6 Praktische Beispiele" ist mir etwas aufgefallen. Die Case Anweisung ist ziemlicher Murks. Ja sie funktioniert so aber das Case von Delphi dürfte schneller sein. In Delphi gibt es 2 unterschiedliche Cases. Entweder die Sprungadressen werden in ein kleines Konstanten Array gepackt. Oder aber die Werte werden besonders verglichen. Also nicht mit ist gleich das oder das, sondern mit einem Ausschlussverfahren (Binärer Baum in Code gegossen). Das sieht dann zwar ziemlich wüst aus aber dadurch benötigt man maximal ca 6-7 Vergleiche bei einem Case mit ca 30 Werten.
Was ich damit eigentlich sagen will. Nur weil man Assembler verwendet heißt es nicht gleich, dass es schneller werden muss. Gut optimierter Pascalcode reicht in vielen Fällen sogar aus und der muss nicht mal langsamer sein. Allerdings kann es nicht schaden, wenn man weiß was in der CPU eigentlich macht.
An besonders zeitkritischen Stellen lohnt es sich aber bestimmt mal einen Blick in den Assemblercode zu werfen. Ich habe schon ein paar Mal gesehen, dass Delphi Register auf den Stack packt und diese sofort im Anschluss wieder vom Stack in die Register packt. Unnütze arbeit. Warum auch immer er das macht? Wenn Zeit wichtig ist, dann kann so etwas durch Assembler vermieden werden. Bzw die Benutzung des Stacks optimiert werden. Wenn nicht sogar ganz auf den Stack verzichtet werden kann.
Besonders Effektiv wird Assembler aber dann, wenn man neuere Technologien einsetzt. Also MMX, 3D NOW, SSE, SSE2 etc. Damit ist es dann möglich mehrere (2, 4, 8 oder 16) Werte gleichzeitig zu berechnen und einen gehörigen Geschwindigkeitsschub zu erzielen. Ist aber wiederrum nicht für alles Einsetzbar. Aber Delphi benutzt so etwas gar nicht. Was auch irgendwie nicht so einfach zu entscheiden wäre vom Kompiler.
In den
Literaturhinweisen von Dr. Ing. Karl-Heinrich Schmidt [
http://homepages.fh-giessen.de/~hg13025/literatur.htm] befinden sich PDFs von Prof. Dr. Klaus Wüst. Diese Dokumente erheben sicher nicht den Abspruch auf absolute Vollständigkeit dafür finde ich aber speziell die MMX Befehle sehr anschaulich dargestellt.
Und das Buch Assembler "GE-PACKT von Joachim Rohde, mitp-Verlag" ist ein sehr gutes Nachschlagewerk.
Delete - Fr 01.02.08 00:40
yep lossy,
wobei man sagen muss, dass man ggf. zuerst noch die logik überdenken sollte, wie auch den programmaufbau... und erst wenn wirklich alle features der hochsprache ausgereizt sind ... und das progy noch zu langsam ist, wird zum assembler gegriffen... das heisst, in aller regel, sehr sehr selten.
grüsse
GG
elundril - Fr 01.02.08 15:32
gibts dazu auch irgendwie Links usw. wo steht was man vemeiden sollte, was man tun sollte usw???
lg elundril
Lossy eX - Fr 01.02.08 17:05
Es gibt leider kein Patentrezept. Außer den ziemlich abgedroschenen Hinweis, dass man so wenig wie möglich machen sollte. Das wiederrum bezieht sich auf 2 Dinde. Jedes mal, wenn man auf Speicher zugreift muss die CPU den Cache bemühen. Im schlimmsten Falle befindet sich der Speicher nicht im Cache und dann muss auch noch der RAM bemüht werden. Deswegen so wenig wie möglich Zugriffe auf den Speicher. Wenn möglich sogar auch nur mit den Registern arbeiten.
Das andere sind normale Befehle. Das richtet sich leider danach was man als minimum voraussetzen möchte. Es gibt immer wieder neuere Befehle die mehr Aktionen auf einen Schlag durchführen können. So zum Beispiel CMOV (Conditional MOV). Dieses wird nur ausgeführt, wenn ein Flag gesetzt ist. Also CMOVG (Greater) ist vergleichbar mit einem JG (Jump Greater) aber halt ein MOV. Und da muss man halt schauen, dass nicht zu viele Befehle ausgeführt werden.
Im übrigen solltest du dich mit der CPU Ansicht vom Delphi anfreunden, wenn noch nicht passiert.
Interessant könnte evtl. das
Fastcode Project [
http://www.fastcodeproject.org/] sein. Das beschäftigt sich damit einzelne Methoden bis zur perversion zu optimieren. Allerdings kann ich meinen Augen so etwas nur ein Anfang sein. Siehe unten.
Außerdem auch sehr interessant ist
die Seite von Dennis Kjaer Christensen [
http://dennishomepage.gugs-cats.dk/BASM-filer/BASMForBeginners.htm]. Auch wenn sie richtig krank aussieht. Dort hat er sich ein paar Methode genommen und hat diese Analysiert und zeigt Schritt für Schritt wie er sie optimiert. Auf jeden Fall wichtig um selber seine Funktionen zu optimieren.
Und das ist eigentlich auch das Wichtigste. Zu erkennen wo sich Flaschenhälse befinden. Den Lerneffekt mal außen vor gelassen. Wenn man hergeht und einfach Methoden nach Assembler umschreibt wird der Geschwindigkeitsvorteil davon eher verhalten sein. Denn um so kleiner die Methoden um so besser bekommt Delphi so etwas meistens auch schon hin. Viel Wichtiger ist sich anzuschauen wo wirklich Zeit verbraten wird. Also mit einem Profiler schauen oder im Code messen wie oft welche Methoden aufgerufen werden und wie viel Zeit diese benötigen. Wenn man das weiß, dann weiß man auch wo genau man einen Hebel ansetzen muss. Es nützt nichts eine Methode von 40 auf 5 ms zu beschleunigen, wenn diese nur 2 Mal aufgerufen wird. Dann lieber die von 2 ms auf 1,5 ms beschleunigen, wenn die 1 Mio Mal aufgerufen wird.
Allerdings kann man nicht gleich zu Begin alles. Also man muss sich auch schon Methoden nehmen die man eigentlich gar nicht optimieren müsste. Aber wenn man von Assembler keine Ahnung hat dann nützt es nichts. Ich weiß zwar teilweise welche Befehle es gibt aber für mich ist auch vieles zu hoch. Und außer zum Lernen oder besonders wichtigen Stellen vermeide ich Assembler auch.
Allesquarks - Fr 01.02.08 22:37
Nun ja ich war auch mal der totale Assembler Fan, aber bin wieder ein wenig davon abgekommen. In den meisten Berechen ist ein guter Compiler um längen besser als man selber, denn wer hat schon einmal die hunderten Seiten Referenzmaterial von amd oder Intel zu nur einer Generation gelesen und beachtet die dann auch.
Dennoch denke ich es bleibt ein (großes) Feld wo es nützlich ist: Es gibt teilweise Fähigkeiten der Prozessoren, die die Hochsprache so nicht ansprechen kann. Zu nennen wäre da ganz basal adc. Grundsätzlich gilt ja immer, der Compiler muss erkennen wie er ermitteln kann und je komplexer das Problem desto schwieriger wird das für den.
Leider gibt es in Delphi meiner Meinung nach das riesige Problem, dass die Integration des Assemblers reichlich misslungen ist, man also leider häufig keinen gezielten Eingriff oder Tipp machen kann ohne neue Probleme aufzuwerfen.
Empfehlen kann ich ein Buch vom Addison Wesley Verlag über Assembler. Im Inet ist das reichlich schlecht besprochen aber ich finde gerade für Anfänger vermittelt es gutes Hintergrundwissen und führt einen gut an das "Interpretieren" von Bits heran (signed/unsigned etc).
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!