Operator schneller als Inline Assembler
-
Jetzt noch den Assembler-Code anzeigen.
Mit Alt+F8 oder so.
-
pdelvo schrieb:
Ich habe die Ticks gezählt. Ich habe den Test mehrfach wiederholt. Meine Version braucht bei mir ca. 2400 Ticks, der Operator 2270(Als debug kompiliert, sonst Operator 0(wird wahrscheinlich wegoptimiert)
Debug sagt wenig aus. mach ne Summe aus der Zuweisung und gibd as Ergebnis am Ende aus. Dann kann er das auch im Release nicht wegoptimieren.
-
01271B50 push ebp 01271B51 mov ebp,esp 01271B53 sub esp,0C0h 01271B59 push ebx 01271B5A push esi 01271B5B push edi 01271B5C lea edi,[ebp-0C0h] 01271B62 mov ecx,30h 01271B67 mov eax,0CCCCCCCCh 01271B6C rep stos dword ptr es:[edi] 01271B6E mov eax,dword ptr [i] 01271B71 add eax,dword ptr [j]Er ist bei beiden Versionen vollkommen identisch.
Schlimm ist das zwar nicht, aber es verwundert mich.Menu Debuggen/Fenster/Disassembly
Gruß pdelvo
-
Registrierter Troll schrieb:
Welchen Code ein x-beliebiger Compiler auf einer x-beliebigen Plattform erzeugt und wie schnell oder langsam der erzeugte Code ist, scheint mir persönlich wenig mit C++ im Sinne dieses Subforums zu tun haben. Genauso wenig wie x86-Assemblercode hier on-topic ist. Dafür gibt es die Compiler- und Assembler-Subforen, die imho besser passen.
Ich erwarte exemplarische Ergebnisse, die im Prinzip auf alle Plattformen und alle aktuellen Compiler übertragbar sind. Ob der Compiler aus dem + ein ADD oder LEA macht, ist völlig egal. Wichtig sind nur die übertragbaren Sachen, zum Beispiel, daß man nie nie nie seine Summen in Zeitmessprogrammen wegwerfen darf, sondern sie ausgeben muß, weil sonst der Compiler ganze Blöcke wegoptimieren kann. Und daß man die Summen nicht zu einfach berechnen darf, also daß der Compiler statt wiederholtem + ein * machen kann. Und daß der Einsatz von Inline-Assembler das Programm potenziell verlangsamt, weil man den Compiler einschränkt.
-
pdelvo schrieb:
Er ist bei beiden Versionen vollkommen identisch.
Schlimm ist das zwar nicht, aber es verwundert mich.Das ist schlimm! Ich würde an Deiner Stelle jetzt panisch im Kreis laufen. Was hast Du gemessen? Solange der Messfehler nicht geklärt ist, kannst Du nie wieder etwas messen und dem Ergebnis glauben.
-
Ich habe die Ticks, die zwichen der Messung vergangen sind gemessen. Gibt es noch eine bessere Methode?
Gruß pdelvo
-
volkard schrieb:
Jetzt noch den Assembler-Code anzeigen.
Mit Alt+F8 oder so.edit: es ist btw alt+8 ^^
aber den der release-version ^^
ich habs ma selbst gemacht mit msvc im release-mode. er übergibt die fkt-parameter nicht direkt in registern, sondern über den stack... ich hab aber auf die schnelle keine Calling-Convention gefunden, die das behebt... bin mir auch nicht ganz sicher, warum er 2 parameter per stack übergibt und nicht über register wie gesagt: asm deaktiviert eben viele optimierungen...
__declspec(noinline)ist wie immer dazu da, um eine bessere Übersicht zu haben, weil er die Fkt nicht inlined (imho MSVC spezifisch)__declspec(noinline) int _add2(int i, int j) { return i + j; 001B1010 add eax,ecx }__declspec(noinline) int _add(int i, int j) { __asm { mov eax, i 001B1000 mov eax,dword ptr [esp+4] add eax, j 001B1004 add eax,dword ptr [esp+8] }bb
-
unskilled schrieb:
ich hab aber auf die schnelle keine Calling-Convention gefunden, die das behebt... bin mir auch nicht ganz sicher, warum er 2 parameter per stack übergibt und nicht über register wie gesagt: asm deaktiviert eben viele optimierungen...
__fastcall
-
volkard schrieb:
unskilled schrieb:
ich hab aber auf die schnelle keine Calling-Convention gefunden, die das behebt... bin mir auch nicht ganz sicher, warum er 2 parameter per stack übergibt und nicht über register wie gesagt: asm deaktiviert eben viele optimierungen...
__fastcall
hatte ich probiert, aber machte es nur noch schlimmer:
__declspec(noinline) int __fastcall _add(int i, int j) { 00021000 sub esp,8 00021003 mov dword ptr [esp],edx 00021006 mov dword ptr [esp+4],ecx __asm { mov eax, i 0002100A mov eax,dword ptr [esp+4] add eax, j 0002100E add eax,dword ptr [esp] } }bb
-
pdelvo schrieb:
Ich habe die Ticks, die zwichen der Messung vergangen sind gemessen. Gibt es noch eine bessere Methode?
Mein erprobtes Schema: 1000 kleine Messungen machen und die nehmen, die am wenigsten Zeit brauchte. Immer, wenn in der Schleife eine bessere Zeit gefunden wurde, den Zähler wieder auf 1000 stellen.
Damit kriegst Du gerne fünf korrekte Stellen.