viewtopic.php?t=22128&hilit=3DDrawing
hat mich inspiriert, die SSE Beschleunigung unter die Lupe zu nehmen.
Eine grundsätzliche Beschreibung dazu findet man unter https://wiki.freepascal.org/SSE/de.
Mir ging es um die Beschleunigung, die man damit evtl. rausholen kann.
Ich habe die klassische Version Vector4-Addition als Macro mit der SSE Version als Procedure verglichen.
Es ging mir darum, zu sehen, ob SSE trotz zusätzlichem Prodecdure-Aufruf schneller ist als die klassiche Version
ohne Procedure-Aufruf.
Ich habe noch versucht, die SSE-Version auch in ein Macro zu verpacken. Aber das hat nicht geklappt.
Falls jemand weis, ob und wie das evtl. geht. Bitte mitteilen.
hier der Testcode
Code: Alles auswählen
EnableExplicit
Structure TVec4f
v.f[4]
EndStructure
#SSE_USE_SSE = #True
Macro macVec_Add(v0, v1, Res)
v0\v[0]= v0\v[0] + v1\v[0]
v0\v[1]= v0\v[1] + v1\v[1]
v0\v[1]= v0\v[2] + v1\v[2]
v0\v[1]= v0\v[3] + v1\v[3]
EndMacro
Procedure Vec_Add(*v0.TVec4f, *v1.TVec4f, *Res.TVec4f)
; Result[0] = v0[0] + v1[0]
; Result[1] = v0[1] + v1[1]
; Result[2] = v0[2] + v1[2]
; Result[3] = v0[3] + v1[3]
CompilerIf #SSE_USE_SSE
CompilerIf #PB_Compiler_64Bit
!Mov rax, [p.p_v0]
!Mov rdx, [p.p_v1]´
!Movups Xmm0, [rax]
!Movups Xmm1, [rdx]
!Addps Xmm1, Xmm0
!Mov eax, [p.p_Res]
!Movups [rax], Xmm1
CompilerElse
!Mov eax, [p.p_v0]
!Mov edx, [p.p_v1]
!Movups Xmm0, [eax]
!Movups Xmm1, [edx]
!Addps Xmm1, Xmm0
!Mov eax, [p.p_Res]
!Movups [eax], Xmm1
CompilerEndIf
CompilerElse
With *res
\v[0]= v0\v[0] + v1\v[0]
\v[1]= v0\v[1] + v1\v[1]
\v[1]= v0\v[2] + v1\v[2]
\v[1]= v0\v[3] + v1\v[3]
EndWith
CompilerEndIf
EndProcedure
Define.i t1, t2, I, J
Define.TVec4f A, B, C
A\v[0] = 1
A\v[1] = 2
A\v[2] = 3
A\v[3] = 4
B\v[0] = 1
B\v[1] = 2
B\v[2] = 3
B\v[3] = 4
#cstRounds = 10000000
t1 = ElapsedMilliseconds()
For I = 0 To #cstRounds
Vec_Add(A, B, C)
Next
t1 = ElapsedMilliseconds() - t1
t2 = ElapsedMilliseconds()
For I = 0 To #cstRounds
macVec_Add(A, B, C)
Next
t2 = ElapsedMilliseconds() - t2
Debug C\v[0]
Debug C\v[1]
Debug C\v[2]
Debug C\v[3]
MessageRequester("Execution times", "SSE : = " + t1 + #CRLF$ + "Classic : = " + T2)
mit Debuger: SSE = 1104ms classic = 621
ohne Debugger: SSE=12ms classic = 57
D.h. mit Debugger bremst der zusätzliche Procedure-Aufruf aus.
Ohne Debugger gewinnt die SSE-Version um fast den Faktor 5.
Im Free-Pascal Wiki ist eine Beschleunigung von 8-9 angegeben.
D.h. der Procedrue-Aufruf schluckt noch 3-4!
Für das C-Backend kann man das leider nicht verwenden!
Ich gehe aber davon aus, dass der C-Compiler evtl. MMX und SSE Regisster
besser automatisch optimieren kann. Das könnte der Grund sein, warum die Framerates
bei Verwendung des C-Backends teilweise deutlich höher sind.