Einzelnen Beitrag anzeigen

Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.063 Beiträge
 
Delphi XE2 Professional
 
#25

Re: Ein bisschen InlineAssembler hilfe :)

  Alt 6. Dez 2009, 17:00
Der Threadersteller war mit dem Zeitbedarf des in #1 gezeigten Pascal-Codes unzufrieden, vermutete, daß ein Assembler-Code schneller sein könnte und bat um Hilfe bei der Umsetzung.
Einige der Kommentare animierten mich, dieses Thema aufzugreifen. Das Resultat findet ihr im Attachment.

Zitat:
Ich denke mal bei solch trivialen Operationen bringt es keinen Geschwindigkeitsvorteil, wenn man sie in Assembler umsetzt.
Zitat:
Das ließe sich zwar übersetzen, aber das würde wie schon gesagt eher keinen Geschwindigkeitsvorteil bringen.. eher das Gegenteil
Doch, gerade bei solch trivialen Operationen läßt sich durch einen guten Assembler-Code viel erreichen, es sei denn man sähe eine Verbesserung um 800-1000 % als "keinen Geschwindigkeitsvorteil" an.
Natürlich bringt es nicht viel, wenn man sich im Debug-Mode anschaut, was der Compiler aus dem Source-Code gemacht hat, dieses abtippt und dann als die optimierte Assembler-Version ansieht.

Zitat:
PS: wir hatten hier schon ein paar Mal, daß die hochoptimierten (Versuche von Menschen) ASM-Codes wesentlich langsamer oder wenigstens/zumindestens genauso schnell waren, wie die optimierten Delphi-Codes aus 'nem Pascal-Compiler.
Die waren dann aber nicht von mir.

Zitat:
600% + (Amd64 SSE3) müssten locker drin sein.
Und auch das ist noch pessimistisch.

Das anhängende Programm enthält 9 unterschiedliche Code-Versionen sowie die Möglichkeit diese bezüglich Performance zu testen. Ich glaube, daß die Oberfläche mehr oder weniger selbsterklärend ist, habe aber einen Hilfefile beigefügt, der mit der F1-Taste angezeigt wird. Es wird vorausgesetzt, daß SSE2 verfügbar ist.

Die Routinen:
1) "PAS_SC (SC=Single Core)
Das ist im Prinzip der vom Threadersteller vorgegebene Code. Diese Version ist nicht multicorefähig. Bei ihr kann nur der Zielwert vorgegeben werden und dieser muß integer sein.
2) "FPU_SC"
Das ist die Übersetzung in Assembler. Auch diese Routine ist nicht multicorefähig und auch hier kann nur der Zielwert vorgegeben werden, der allerdings auch eine Fließkommazahl sein darf.
3) "MMX_SC"
Ebenfalls eine nicht multicorefähige Assembler-Routine, die aber mit den jeweils unteren Hälften der XMM-Register arbeitet.
4-6) "PAS_A", "FPU_A", "MMX_A"
Das sind multicorefähige Versionen. Bei der XMM-Routine wird die volle Breite der XMM-Register genutzt.
7-9) "PAS_B", "FPU_B", "XMM_B"
Hier wurde der Vorschlag aus #24 aufgegriffen, nicht nach jeder Rechnung zu prüfen, ob die Abbruchbedingung erfüllt ist sondern z.B. nur alle 16 Mal zu prüfen. Das Ergebnis ist eher ernüchternd, weil so gut wir keine Verbesserung zu verzeichnen ist.

Die nachstehende Tabelle zeigt ermittelte Rechenzeiten (CPU Intel Core 2 Duo E8400 3.0 GHz) für die verschiedenen Routinen. Es zeigt sich, daß Verbesserungen der Performance um den Faktor 8 bis 10 erreicht werden. Bei einer Quad-Core CPU dürften die Verbesserung deutlich höher sein.

Code:
Zielwert  20       20      25     25
Cores      1        2       1      2
Zeit in   ms      ms      s     s
-------- ----     ----     ---    ---
PAS_SC  4420     -        649      -
FPU_SC  2160     -        306      -
XMM_SC  2270     -        325      -
PAS_A   4160     2130     661    330
FPU_A   2060     1130     298    150
XMM_A   985       547     135     68
PAS_B   4200     2170     612    308
FPU_B   2080     1090     299    151
XMM_B   968       547     136     68
Angehängte Dateien
Dateityp: zip harmonicseries_556.zip (286,4 KB, 25x aufgerufen)
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat