Seite 1 von 2

PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 12.07.2021 23:56
von TheCube
Hatte mal Lust mir einen kleinen Geschwindigkeits-Vergleich "SwapLong" zwischen PB-fasm (auch mit integr. ASM)
und dem C-Backend inkl. Optimierung zu schreiben.

Code: Alles auswählen

CompilerIf #PB_Compiler_Backend=#PB_Backend_C
  Debug "c backend"
CompilerElse
  Debug "fasm backend"
CompilerEndIf

CompilerIf  #PB_Compiler_Backend=#PB_Backend_Asm
  Procedure.l SwapLong(Value.l)
	;	!MOV Eax, [p.v_Value]
	;	!BSWAP Eax
		ProcedureReturn
	EndProcedure
CompilerEndIf
	
Procedure SwapLong1(e.l)    ; Quelle PB-Forum
 ProcedureReturn (e & $ff) << 24 + (e & $ff00) << 8 + (e >> 8) & $ff00 + (e >> 24) & $ff
EndProcedure

Procedure SwapLong2(num.l)  ; Quelle Fremd-Forum
  ProcedureReturn ((num & $ff000000) >> 24) | ((num & $00ff0000) >> 8) | ((num & $0000ff00) << 8) | (num << 24)
EndProcedure

; ------------------------------------------------------------------------------------------------------------------
CompilerIf  #PB_Compiler_Backend=#PB_Backend_Asm
  Debug Hex(SwapLong($11223344), #PB_Long)
  title$=" Messung: ASM-Compiler"
CompilerElse
  title$=" Messung: C-Compiler"
CompilerEndIf
Debug Hex(SwapLong1($11223344), #PB_Long)
Debug Hex(SwapLong2($11223344), #PB_Long)

x.l=0

CompilerIf  #PB_Compiler_Backend=#PB_Backend_Asm
StartTime.q = ElapsedMilliseconds()     ; ermittelt den aktuellen Wert
For i=1 To 80000000
  x=SwapLong($11223344)
Next
Text$=Text$+"ASM :" + Str(ElapsedMilliseconds() - StartTime) + " ms" + #CRLF$ 
Debug ElapsedMilliseconds() - StartTime ;
CompilerEndIf

StartTime = ElapsedMilliseconds()     ; ermittelt den aktuellen Wert
For i=1 To 80000000
  x=SwapLong1($11223344)
Next
Text$=Text$+"PB_ :" + Str(ElapsedMilliseconds() - StartTime) + " ms" + #CRLF$ 
Debug ElapsedMilliseconds() - StartTime ;

StartTime = ElapsedMilliseconds()     ; ermittelt den aktuellen Wert
For i=1 To 80000000
  x=SwapLong2($11223344)
Next
Text$=Text$+"Ext :" + Str(ElapsedMilliseconds() - StartTime) + " ms" + #CRLF$ 
Debug ElapsedMilliseconds() - StartTime ;

MessageRequester(title$, Text$, #PB_MessageRequester_Ok)

Debug "--------------" : Debug "Fertig."
Mach ich daraus eine fasm-kompilierte EXE ist alles gut, das integrierte ASM ist erwartungsgemäß am schnellsten.
Mach ich daraus eine C-kompilierte EXE wird leider nur "0ms" angezeigt, die Test-For-Next-Schleifen wurden wohl wegoptimiert.

Mit welchem kleinen Trick kann ich das wegoptimieren bestimmter Teile in PB am besten verhindern ? (Optimieren Aus ist keine Option ....)

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 13.07.2021 07:30
von GPI
du könntest einfach

Code: Alles auswählen

For i=1 To 80000000
  x=SwapLong1(i)
Next
schreiben, dann sollte nichts mehr optimiert werden. Wobei ich es komisch fände, wenn der Compiler hier überhaupt optimiert.

Ansonsten: Wenn du die Geschwindigkeit messen willst, sollte kein Debugger laufen, erstell die Ausgabe in eine Konsole oder per Messagerequester. Der Debugger verfälsch ungemein den code.

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 13.07.2021 08:08
von STARGÅTE
GPI hat geschrieben: 13.07.2021 07:30 du könntest einfach
CODE: ALLES AUSWÄHLEN

For i=1 To 80000000
x=SwapLong1(i)
Next
schreiben, dann sollte nichts mehr optimiert werden. Wobei ich es komisch fände, wenn der Compiler hier überhaupt optimiert.
Nö, das alleine reicht nicht. "Leider" sieht der Optimierer, dass "x" nie wieder gebraucht wird, wozu dann also ausrechnen.
Das ausgerechnete "x" müsste also direkt in der Schleife wieder weiter verwendet werden.
Zum Beispiel:

Code: Alles auswählen

For i=1 To 80000000
  x=SwapLong1(x+i)
Next

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 13.07.2021 12:26
von mk-soft
Dafür gibt es __buildin Funktionen in GCC

Link: https://www.purebasic.fr/english/viewto ... 12&t=77563

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 13.07.2021 13:15
von STARGÅTE
mk-soft hat geschrieben: 13.07.2021 12:26 Dafür gibt es __buildin Funktionen in GCC

Link: https://www.purebasic.fr/english/viewto ... 12&t=77563
Der Link führt zu bswap.
Die Frage war aber, wie man "das wegoptimieren bestimmter Teile in PB am besten verhindern [kann] ? (Optimieren Aus ist keine Option ....)"?

Ich meine mir ist auch klar, dass der Optimierer ja genau das machen soll, aber für Speed-Tests ist das echt blöd, weil man dann den eigentlichen Code umschreiben muss, was die Zeitmessung ja wieder verändert.

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 13.07.2021 15:09
von DrShrek
STARGÅTE hat geschrieben: 13.07.2021 13:15 Ich meine mir ist auch klar, dass der Optimierer ja genau das machen soll, aber für Speed-Tests ist das echt blöd, weil man dann den eigentlichen Code umschreiben muss, was die Zeitmessung ja wieder verändert.
Was ist der Sinn des Speedtests?
Gerade das macht doch erst den Sinn...die Optimierung durch den Compiler.
Langsam programmieren ist einfach.
Code optimieren teuer.
Deswegen ist das eine kaufentscheidende Funktion eines Compiler.

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 13.07.2021 16:03
von STARGÅTE
Ich glaube es geht darum zu vergleichen wie schnell der ASM Code (!BSWAP eax) im ASM-backend im Vergleich zum PB Code im (optimieten) C-backend bzw. der C-Code im (optimieten) C-backend ist.

Zumindest stelle ich mir eine ähnliche Frage, nämlich ob ich auf meine ASM-Optimierung verzichten kann weil der PB-Code im (optimieten) C-backend ähnliche Zeiten liefert. Bislang sieht es (noch) nicht danach aus. Soll heißen, der C-Optimierer ist zwar echt gut, kommt aber an reinen ASM-Code nicht ran. (Ein Beispiel gab es hier: https://www.purebasic.fr/english/viewto ... 55#p571255)

Hängt halt ein bisschen davon ab "wo man hin will" mit deinem Programm.

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 13.07.2021 23:18
von TheCube
War etwas länger offline, sorry.
STARGÅTE hat meinen kleinen Vergleichsversuch genau richtig gedeutet, es geht nicht direkt um ein Speedtest sondern um den Vergleich
was der C-Optimierer aus gegebenen Code macht. Der SwapLong2() stammt - glaube ich - aus Stackoverflow und es wurde dort geschrieben,
das der Optimierer das zu einem !BSWAP eax zusammenfasst. Deshalb auch die SwapLong1()-Codevariante und natürlich die ASM-Version als Referenz.

Hätte SwapLong2() gleiche Zeiten wie die ASM-Variante errreicht (natürlich ohne Debugger :wink: ) wäre ich schwer beeindruckt,
aber so kann ich das wg. des Wegoptimierens erstmal nicht testen.

In C selbst (bin da eher gelegentlich unterwegs) gibt es ja Kniffe die Optimierer zu beeinflussen, wie z.B.
bzgl.Wegoptimieren von Variablen (für Interrupts o.ä.) -> Wird gerne mit Variablendeklaration als 'volatile' verhindert

Klar in 99% der Fälle soll der Optimierer sein Bestes geben und auch Überflüssiges rausschmeissen, aber selten soll vielleicht doch
ein bestimmter Codeteil (trotz vermeintlicher Sinnlosigkeit) optimiert erhalten bleiben.
Vielleicht beglückt aus Fred ja später mit C-Optimizer-Befehlen für der Quellcode wie beim Debugger: z.B. CoptLevel, DisableCopt und EnableCopt

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 14.07.2021 02:05
von DrShrek
Also warum ein Codeteil der sinnlos ist erhalten bleiben soll erschließt sich mir nicht.
Ein Beispiel:
int a = 10;
a++;
a---;
Print(a);

Was macht das Sinn?
a++;
a---;
Kann entfernt werden.

Re: PB alpha3 - C-backend: Wegoptimieren verhindern

Verfasst: 14.07.2021 06:54
von GPI
STARGÅTE hat geschrieben: 13.07.2021 08:08 Nö, das alleine reicht nicht. "Leider" sieht der Optimierer, dass "x" nie wieder gebraucht wird, wozu dann also ausrechnen.
oh ernsthaft? Wird dazu auch die Procedure SwapLong() von Optimierer angeschaut? Muss eigentlich, weil ansonsten wäre so eine Optimierung grob fahrlässig. Der Optimierer muss ja wissen, ob nur X berechnet wird, oder ob bspw. nur eine Fehler-/Ok-meldung zurückgegeben wird, die man verwirft.