Sign in Join
Wiki copytemporary

SSE/de: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## SSE
22
33Mit der SSE-Erweiterung der Modernen CPUs, kann bis zu 8-9fache Geschwindigkeitssteigerung erzielen, gegenüber klassischen FPU-Operationen.
44
55Am besten werden 4x Vektoren und 4x4 Matrizen unterstützt, dies wird sehr viel bei OpenGL gebraucht.
66
77Die Assembler-Blöcke sind so angepasst, das sie auf 32Bit und 64Bit CPU laufen, vorausgesetzt, sie sind Intel kompatibel ARM (Raspberry) geht nicht, die haben einen anderen Befehlssatz.
88
99Folgende Beispiele sollten alle ab Intel-Core laufen.
1010
1111Teilweise, kann Lazarus von Haus auf SSE und AVX verwenden, dafür muss folgendes unter *"Projekt --\> Projekteinstellungen... --\> Benutzerdefinierte Einstellungen"* ergänzt werden:
1212
1313 -al
1414 -CfAVX2
1515 -CpCOREAVX2
1616 -O3
1717 -Sv
1818 -OpCOREAVX2
1919 -OoFASTMATH
2020
2121Dies hat auf die direkten Assembler Funktionen keinen Einfluss.
2222
2323### Hilfs- Deklarationen und Funktionen
2424
2525``` pascal
2626{$asmmode intel}
2727
2828type
2929 TVector4f = array[0..3] of Single;
3030 TMatrix = array[0..3] of TVector4f;
3131
3232var
3333 a: TVector4f = (1.0, 2.0, 3.0, 4.0);
3434 b: TVector4f = (5.0, 6.0, 7.0, 8.0);
3535 c: TVector4f;
3636 f: single = 2.0;
3737
3838procedure WriteVector(v: TVector4f);
3939begin
4040 WriteLn(v[0]: 8: 4, ' ', v[1]: 8: 4, ' ', v[2]: 8: 4, ' ', v[3]: 8: 4);
4141end;
4242```
4343
4444### Die wichtigsten Vektor-Operationen
4545
4646#### Vektoren Addieren
4747
4848Klassisch:
4949
5050``` pascal
5151Result[0] := v0[0] + v1[0];
5252Result[1] := v0[1] + v1[1];
5353Result[2] := v0[2] + v1[2];
5454Result[3] := v0[3] + v1[3];
5555```
5656
5757SSE beschleunigt:
5858
5959``` pascal
6060function Vec_Add(const v0, v1: TVector4f): TVector4f; assembler; nostackframe; register;
6161asm
6262 Movups Xmm0, [v0]
6363 Movups Xmm1, [v1]
6464 Addps Xmm1, Xmm0
6565 Movups [Result], Xmm1
6666end;
6767```
6868
6969#### Vektoren Subtrahieren
7070
7171Klassisch:
7272
7373``` pascal
7474Result[0] := v0[0] - v1[0];
7575Result[1] := v0[1] - v1[1];
7676Result[2] := v0[2] - v1[2];
7777Result[3] := v0[3] - v1[3];
7878```
7979
8080SSE beschleunigt:
8181
8282``` pascal
8383function Vec_Add(const v0, v1: TVector4f): TVector4f; assembler; nostackframe; register;
8484asm
8585 Movups Xmm0, [v0]
8686 Movups Xmm1, [v1]
8787 Subps Xmm1, Xmm0
8888 Movups [Result], Xmm1
8989end;
9090```
9191
9292#### Vektoren Multiplizieren
9393
9494Klassisch:
9595
9696``` pascal
9797Result[0] := v0[0] * v1[0];
9898Result[1] := v0[1] * v1[1];
9999Result[2] := v0[2] * v1[2];
100100Result[3] := v0[3] * v1[3];
101101```
102102
103103SSE beschleunigt:
104104
105105\<syntaxhighlight lang="pascal\> function Vec_Add(const v0, v1: TVector4f): TVector4f; assembler; nostackframe; register; asm
106106
107107`        Movups  Xmm0, [v0]`\
108108`        Movups  Xmm1, [v1]`\
109109`        Mulps   Xmm1, Xmm0`\
110110`        Movups  [Result], Xmm1  `
111111
112112end;
113113
114-</syntaxhighlight>
115-
116114#### Vektoren Dividieren
117115
118116Klassisch:
119117
120118``` pascal
121119Result[0] := v0[0] / v1[0];
122120Result[1] := v0[1] / v1[1];
123121Result[2] := v0[2] / v1[2];
124122Result[3] := v0[3] / v1[3];
125123```
126124
127125SSE beschleunigt:
128126
129127``` pascal
130128function Vec_Add(const v0, v1: TVector4f): TVector4f; assembler; nostackframe; register;
131129asm
132130 Movups Xmm0, [v0]
133131 Movups Xmm1, [v1]
134132 Divps Xmm1, Xmm0
135133 Movups [Result], Xmm1
136134end;
137135```
138136
139137#### Vektoren Tauschen
140138
141139Klassisch:
142140
143141``` pascal
144142Result[0] := v[3];
145143Result[1] := v[2];
146144Result[2] := v[1];
147145Result[3] := v[0];
148146```
149147
150148SSE beschleunigt:
151149
152150``` pascal
153151function Vec_Swap(const v: TVector4f): TVector4f; assembler; nostackframe; register;
154152asm
155153 Movups Xmm0, [v]
156154 Pshufd Xmm1,Xmm0, $1b
157155 Movups [Result], Xmm1
158156end;
159157```
160158
161159#### Vektoren Skalieren
162160
163161Klassisch:
164162
165163``` pascal
166164Result[0] := v[0] * f;
167165Result[1] := v[1] * f;
168166Result[2] := v[2] * f;
169167Result[3] := v[3] * f;
170168```
171169
172170SSE beschleunigt:
173171
174172``` pascal
175173function Vec_Multiply_All(const v: TVector4f; f: Single): TVector4f; assembler; nostackframe; register;
176174asm
177175Movss Xmm0, f
178176Pshufd Xmm0, Xmm0, $00
179177Movups Xmm1, [v]
180178Mulps Xmm1,Xmm0
181179Movups [Result], Xmm1
182180end;
183181```
184182
185183### Beispiele
186184
187185``` pascal
188186procedure TForm1.Button1Click(Sender: TObject);
189187var
190188 a: TVector4f = (1.0, 2.0, 3.0, 4.0);
191189 b: TVector4f = (5.0, 6.0, 7.0, 8.0);
192190 c: TVector4f;
193191
194192 f: single = 2.0;
195193
196194begin
197195 WriteLn('Addieren');
198196 c := Vec_Add(a, b);
199197 WriteVector(c);
200198 WriteLn();
201199
202200 WriteLn('Subtrahieren');
203201 c := Vec_Sub(b, a);
204202 WriteVector(c);
205203 WriteLn();
206204
207205 WriteLn('Multipizieren');
208206 c := Vec_Multiply(b, a);
209207 WriteVector(c);
210208 WriteLn();
211209
212210 WriteLn('Dividieren');
213211 c := Vec_Divide(b, a);
214212 WriteVector(c);
215213 WriteLn();
216214
217215 WriteLn('Vertauschen');
218216 c := Vec_Swap(a);
219217 WriteVector(c);
220218 WriteLn();
221219
222220 WriteLn('Alle Multipizieren');
223221 f := 2.2;
224222 c:=Vec_Multiply_All(a, f);
225223 WriteVector(c);
226224 WriteLn();
227225
228226end;
229227```
230228
231229### Vektoren multiplizieren
232230
233231Vektor mit einer Matrix multiplizieren.
234232
235233``` pascal
236234
237235{$asmmode intel}
238236
239237function VectorMultiplySSE(const mat: TMatrix; const vec: TVector4f): TVector4f; assembler; nostackframe; register;
240238asm
241239 Movups Xmm4, [mat + $00]
242240 Movups Xmm5, [mat + $10]
243241 Movups Xmm6, [mat + $20]
244242 Movups Xmm7, [mat + $30]
245243 Movups Xmm2, [vec]
246244
247245 // Zeile 0
248246 Pshufd Xmm0, Xmm2, 00000000b
249247 Mulps Xmm0, Xmm4
250248
251249 // Zeile 1
252250 Pshufd Xmm1, Xmm2, 01010101b
253251 Mulps Xmm1, Xmm5
254252 Addps Xmm0, Xmm1
255253
256254 // Zeile 2
257255 Pshufd Xmm1, Xmm2, 10101010b
258256 Mulps Xmm1, Xmm6
259257 Addps Xmm0, Xmm1
260258
261259 // Zeile 3
262260 Pshufd Xmm1, Xmm2, 11111111b
263261 Mulps Xmm1, Xmm7
264262 Addps Xmm0, Xmm1
265263
266264 Movups [Result], Xmm0
267265end;
268266```
269267
270268### Matrizen multiplizieren
271269
2722702 Matrizen mutiplizieren.
273271
274272Für eine Matrix-Multiplikation, hat man mit SSE etwa 8-9fache Geschwindigkeitssteigerung, gegenüber klassichen Single-Multiplikationen.
275273
276274``` pascal
277275
278276{$asmmode intel}
279277
280278function MatrixMultiplySSE(const M0, M1: TMatrix): TMatrix; assembler; nostackframe; register;
281279asm
282280 Movups Xmm4, [M0 + $00]
283281 Movups Xmm5, [M0 + $10]
284282 Movups Xmm6, [M0 + $20]
285283 Movups Xmm7, [M0 + $30]
286284
287285 // Spalte 0
288286 Movups Xmm2, [M1 + $00]
289287
290288 Pshufd Xmm0, Xmm2, 00000000b
291289 Mulps Xmm0, Xmm4
292290
293291 Pshufd Xmm1, Xmm2, 01010101b
294292 Mulps Xmm1, Xmm5
295293 Addps Xmm0, Xmm1
296294
297295 Pshufd Xmm1, Xmm2, 10101010b
298296 Mulps Xmm1, Xmm6
299297 Addps Xmm0, Xmm1
300298
301299 Pshufd Xmm1, Xmm2, 11111111b
302300 Mulps Xmm1, Xmm7
303301 Addps Xmm0, Xmm1
304302
305303 Movups [Result + $00], Xmm0
306304
307305 // Spalte 1
308306 Movups Xmm2, [M1 + $10]
309307
310308 Pshufd Xmm0, Xmm2, 00000000b
311309 Mulps Xmm0, Xmm4
312310
313311 Pshufd Xmm1, Xmm2, 01010101b
314312 Mulps Xmm1, Xmm5
315313 Addps Xmm0, Xmm1
316314
317315 Pshufd Xmm1, Xmm2, 10101010b
318316 Mulps Xmm1, Xmm6
319317 Addps Xmm0, Xmm1
320318
321319 Pshufd Xmm1, Xmm2, 11111111b
322320 Mulps Xmm1, Xmm7
323321 Addps Xmm0, Xmm1
324322
325323 Movups [Result + $10], Xmm0
326324
327325 // Spalte 2
328326 Movups Xmm2, [M1 + $20]
329327
330328 Pshufd Xmm0, Xmm2, 00000000b
331329 Mulps Xmm0, Xmm4
332330
333331 Pshufd Xmm1, Xmm2, 01010101b
334332 Mulps Xmm1, Xmm5
335333 Addps Xmm0, Xmm1
336334
337335 Pshufd Xmm1, Xmm2, 10101010b
338336 Mulps Xmm1, Xmm6
339337 Addps Xmm0, Xmm1
340338
341339 Pshufd Xmm1, Xmm2, 11111111b
342340 Mulps Xmm1, Xmm7
343341 Addps Xmm0, Xmm1
344342
345343 Movups [Result + $20], Xmm0
346344
347345 // Spalte 3
348346 Movups Xmm2, [M1 + $30]
349347
350348 Pshufd Xmm0, Xmm2, 00000000b
351349 Mulps Xmm0, Xmm4
352350
353351 Pshufd Xmm1, Xmm2, 01010101b
354352 Mulps Xmm1, Xmm5
355353 Addps Xmm0, Xmm1
356354
357355 Pshufd Xmm1, Xmm2, 10101010b
358356 Mulps Xmm1, Xmm6
359357 Addps Xmm0, Xmm1
360358
361359 Pshufd Xmm1, Xmm2, 11111111b
362360 Mulps Xmm1, Xmm7
363361 Addps Xmm0, Xmm1
364362
365363 Movups [Result + $30], Xmm0
366364end;
367365```
368366
369367Autor: Mathias
370368
371369---
372370*From the Free Pascal wiki, page "SSE/de", as it stood on 2020-01-19 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
373371Category: Deutsch
374372Category: Free Pascal Programmers Guide/de

Back to history