Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64 (https://www.delphipraxis.net/213220-geschwindigkeitsunterschiede-apple-sillicon-intel-win32-win64.html)

areyoudoneyet 18. Jun 2023 13:12

Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
das ist bestimmt eine Anfänger Frage und eventuell den meisten Leuten klar weshalb folgendes, das ich gleich beschreibe so ist wie es ist.
Ich habe gestern ein kleines Tutorial Video von DelphiLernen auf Youtube angeschaut. Und das kleine Programm nachgebaut.

Code:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  sum: Int64;
  StartTime, EndTime, ElapsedTime: Int64;
begin
  StartTime := MilliSecondOfTheDay(Now);

  sum := 0;
  for i := 1 to 1000000000 do
    sum := sum + 1;

  EndTime := MilliSecondOfTheDay(Now);
  ElapsedTime := EndTime - StartTime;

  ShowMessage('Summe: ' + IntToStr(sum) + ' / Zeit: ' + IntToStr(ElapsedTime) + ' ms');
end;
Nichts großartiges.

Ich habe es für alle mir verfügbaren Plattformen kompiliert.

Win32 = 6063ms
Win64 = 390ms
macOS ARM 64 Bit = 1296 ms
macos 64 Bit ( mit rosetta) = 316 ms

in C für Arm mit gcc -O3

2 ms

Swift
41 ms Sekunden

C#
362 ms

Lazarus fpc für intel

421ms

fpc für arm
1624 ms


Was mich etwas wundert das dies in Windows bei 64 und 32 so ein großer unterschied ist, und das bei macOS die Rosetta Variante auch sehr viel schneller ist als die (Native Arm) Version. Selbe Bild beim FPC.

Gut C ist halt einfach schnell, dachte allerdings aus Erzählungen das Delphi nicht arg weit dahinter ist.

Was mir stark gewundert hat das Swift die Schleife so schnell durchläuft und auch das C# das Schneller durchläuft unter Macos als die Delphi variante.

Den Hacken Optimierungen habe ich angekreuzt in Delphi. Eventuell gibt es da noch etwas das man machen könnte.

Mich interessiert einfach woher diese unterschiede kommen. Vielleicht kann mich da jemand kurz aufklären.

Danke :)

himitsu 18. Jun 2023 13:19

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
* wie optimal erzeugt der Compiler den Code
* wie schnell sind die einzelnen verwendeten CPU-Befehle
* was bietet die jeweilige Platform eigentlich für Befehle
* wie gut läuft der Speicherzugriff
* und wie gut die Abarbeitung dieses Codes



Win32 muß langsamer sein, denn bei 64 Bit rechnet die CPU, mit einem "Assembler"-Befehl,
während es unter 32 Bit eine Funktion macht, also viele Assembler-Befehle.

[edit]
Nee, beim ADD wird es direkt gemacht, aber auch mit mehreren Befehlen, denn die 32 Bit-CPU kann ja nur mit 32 Bit rechnen.
MUL, DIV, MOD waren aber Funktionen. (z.B. siehe __llmul in der System.pas)

Delphi-Quellcode:
// Win32
mov eax,[ebp-$10]
mov edx,[ebp-$0c]
add eax,$7b
adc edx,$00
jno $006663d9
call $00498228
mov [ebp-$10],eax
mov [ebp-$0c],edx

// Win64
add qword ptr [rbp+$28],$7b
jno TForm4.FormCreate + $20
call @IntOver
Und wenn man jetzt noch die Überlauf- und Bereichsprüfung wieder deaktiviert, welche nun seit Kurzem standardmäßig aktiv sind. :wall:

Delphi-Quellcode:
mov eax,[ebp-$10]
mov edx,[ebp-$0c]
add eax,$7b
adc edx,$00
mov [ebp-$10],eax
mov [ebp-$0c],edx

versus

add qword ptr [rbp+$08],$7b


PS, bezüglich der Optimierung.
Bei gewissen Rechenoperationen kann es "anders" einfacher gehn.

z.B. aus einem
Delphi-Quellcode:
i * 2
kann oft einfach ein
Delphi-Quellcode:
i shl 1
werden.
Und ein "einfacher" Bit-Shift geht auch mit weniger CPU-Takten, als ein "aufwendiges" mathematisches Rechnen.

areyoudoneyet 18. Jun 2023 13:55

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Danke für die schöne Erklärung!
6 zu 1 mehr Arbeit in der 32 Bit Version, hätte ich nicht gedacht. :)

jaenicke 18. Jun 2023 14:45

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Das hängt aber auch sehr vom konkreten System ab. Bei mir (i5-8600k) braucht Win32 ca. 1400 Millisekunden und Win64 ca. 1600 bzw. im Release 1300 vs. 400. Da ist der Unterschied geringer. Generell ist die Optimierung beim 64-Bit Compiler oft besser.

areyoudoneyet 18. Jun 2023 15:41

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von jaenicke (Beitrag 1523520)
Das hängt aber auch sehr vom konkreten System ab. Bei mir (i5-8600k) braucht Win32 ca. 1400 Millisekunden und Win64 ca. 1600 bzw. im Release 1300 vs. 400. Da ist der Unterschied geringer. Generell ist die Optimierung beim 64-Bit Compiler oft besser.

Verstehe :)

Code:
var
  counter: integer;
  startTime, endTime: TDateTime;
  timeTaken: Double;
begin
  counter := 1;
  startTime := Now; // Startzeit aufzeichnen

  asm
    mov ecx, counter
  @loop_start:
    inc ecx
    cmp ecx, 100000000
    jle @loop_start
    mov counter, ecx
  end;
  endTime := Now;
  timeTaken := MilliSecondSpan(startTime, endTime);
  ShowMessage(FloatToStr(timeTaken) + ' ms');
end;
jetzt nur noch ca. 50 ms für win32


Code:

procedure TForm1.Button1Click(Sender: TObject);
var
   counter:integer;
  startTime, endTime: TDateTime;
  timeTaken: Double;
begin
   counter := 0;
  startTime := Now; // Startzeit aufzeichnen
  while counter <= 100000000 do
    inc(counter);
  endTime := Now; // Endzeit aufzeichnen
  timeTaken := MilliSecondSpan(startTime, endTime); // Berechnung der benötigten Zeit in Millisekunden
  ShowMessage(FloatToStr(timeTaken) + ' ms'); // Zeigt die benötigte Zeit in Millisekunden an

end;
Ich habe jetzt mal den inc versucht. ist egal ob auf mac oder win immer bei ca. 30-60 ms.

d.h. für mich falls ich etwas Inkrementieren muss sollte ich "inc" verwenden anstelle "x := x+1;"

ich find das echt Interresant :) Dachte für mich immer... das ist doch das gleiche...

jaenicke 18. Jun 2023 18:31

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Deine neuen Quelltexte machen aber auch etwas anderes. Anfangs hattest du eine Schleife mit der Änderung der Schleifenvariable und zusätzlich das Inkrementieren eines Wertes. Jetzt hast du nur noch die Schleife. Dass das schneller ist, ist klar.

areyoudoneyet 18. Jun 2023 21:02

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von jaenicke (Beitrag 1523525)
Deine neuen Quelltexte machen aber auch etwas anderes. Anfangs hattest du eine Schleife mit der Änderung der Schleifenvariable und zusätzlich das Inkrementieren eines Wertes. Jetzt hast du nur noch die Schleife. Dass das schneller ist, ist klar.

hm stimmt.

MEissing 19. Jun 2023 10:27

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
int64 ist auf Win32 ist "teuer"

Das ursprüngliche
Code:
var
  i: int64;
auf
Code:
var
  i: integer;
bringt für Win32 schon etliches (6044 -> 736ms)

Stevie 20. Jun 2023 10:34

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von jaenicke (Beitrag 1523520)
Generell ist die Optimierung beim 64-Bit Compiler oft besser.

Dem muss ich widersprechen - eher im Gegenteil. Es ist in diesem konkreten Fall so, dass unter 64bit nativ gerechnet werden kann und unter 32bit ein Int64 auf 2 Register aufgeteilt ist.

Zur Eingangsfrage und den um mehr als Faktor 10 unterscheidenden Ergebnissen kann ich nur sagen: da ist ziemlich sicher irgendwo ein Messfehler oder eine nicht vergleichbare Compilerkonfiguration.

jaenicke 20. Jun 2023 10:57

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Stevie (Beitrag 1523573)
Zur Eingangsfrage und den um mehr als Faktor 10 unterscheidenden Ergebnissen kann ich nur sagen: da ist ziemlich sicher irgendwo ein Messfehler oder eine nicht vergleichbare Compilerkonfiguration.

Das hat ja Matthias schon beantwortet.

Stevie 20. Jun 2023 12:13

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von jaenicke (Beitrag 1523575)
Zitat:

Zitat von Stevie (Beitrag 1523573)
Zur Eingangsfrage und den um mehr als Faktor 10 unterscheidenden Ergebnissen kann ich nur sagen: da ist ziemlich sicher irgendwo ein Messfehler oder eine nicht vergleichbare Compilerkonfiguration.

Das hat ja Matthias schon beantwortet.

Hat er? Ich kann diese Messergebnisse mit Int64 unter Win32 nicht reproduzieren, daher liegt es entweder an den Compilersettings des TE oder seiner Hardware.
Der Overhead von Int64 unter 32bit ist messbar aber keineswegs auch nur annäherend in Bereich x10

Zitat:

Zitat von areyoudoneyet (Beitrag 1523516)
Gut C ist halt einfach schnell, dachte allerdings aus Erzählungen das Delphi nicht arg weit dahinter ist.

Das hier hatte auch noch niemand kommentiert - gcc optimiert hier schon zur Compiletime und erkennt, dass es eine Schleife mit konstanter Anzahl an Durchläufen ist und generiert einfach schon den Wert für sum, so dass zur Laufzeit überhaupt keine Schleife passiert.
Der Messwert bei swift sieht auch aus, als ob da etwas ähnliches passiert.

jaenicke 20. Jun 2023 14:41

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Stevie (Beitrag 1523579)
Der Overhead von Int64 unter 32bit ist messbar aber keineswegs auch nur annäherend in Bereich x10

Bei mir liegt der Unterschied bei etwa Faktor 7. Int64 braucht wie geschrieben ca. 1400 Millisekunden, Integer ca. 200. Und dann ist die 64-Bit Variante bei mir auch langsamer.

mytbo 20. Jun 2023 14:50

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Delphi 11.3 Alexandria, Build Release (Standardeinstellungen), Prozessor Intel(R) Core(TM) i5 3.20GHz
Delphi-Quellcode:
uses
  mormot.core.base,
  mormot.core.perf;

const
  RUN_COUNT = 1000000000;
var
  timer: TPrecisionTimer;
begin
  timer.Start;
  var sum: Int64 := 0;
  for var i: Integer := 1 to RUN_COUNT do
    // sum := sum + 1;
    Inc(sum);

  ShowMessage(Format('Laufzeit: %s (%d us), Summe: %d', [timer.Stop, timer.StopInMicroSec, sum]));
PlattformLaufzeit: Inc(sum)Laufzeit: sum := sum + 1
32 Bit1.82s (1822103 us)1.69s (1693918 us)
64 Bit294.65ms (294654 us)294.85ms (294857 us)

Verwende ich sum in der Ausgabe (ShowMessage) nicht, sehen die Ergebnisse für 32-Bit so aus:
PlattformLaufzeit: Inc(sum)Laufzeit: sum := sum + 1
32 Bit294.92ms (294925 us)1.68s (1688951 us)
Die Werte für 64-Bit ändern sich nicht.

Alle Messwerte in mehreren Durchläufen verifiziert.

Bis bald...
Thomas

MEissing 20. Jun 2023 15:00

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Stevie (Beitrag 1523579)
Zitat:

Zitat von jaenicke (Beitrag 1523575)
Zitat:

Zitat von Stevie (Beitrag 1523573)
Zur Eingangsfrage und den um mehr als Faktor 10 unterscheidenden Ergebnissen kann ich nur sagen: da ist ziemlich sicher irgendwo ein Messfehler oder eine nicht vergleichbare Compilerkonfiguration.

Das hat ja Matthias schon beantwortet.

Hat er?

Ja. Vor allem auf M1 Max getestet. Wo hast du getestet?

Stevie 20. Jun 2023 15:12

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von MEissing (Beitrag 1523585)
Zitat:

Zitat von Stevie (Beitrag 1523579)
Zitat:

Zitat von jaenicke (Beitrag 1523575)
Zitat:

Zitat von Stevie (Beitrag 1523573)
Zur Eingangsfrage und den um mehr als Faktor 10 unterscheidenden Ergebnissen kann ich nur sagen: da ist ziemlich sicher irgendwo ein Messfehler oder eine nicht vergleichbare Compilerkonfiguration.

Das hat ja Matthias schon beantwortet.

Hat er?

Ja. Vor allem auf M1 Max getestet. Wo hast du getestet?

Auf einem i7-12700 - wenn du auf ner ARM CPU x86(-64) Kompilate testest, dann möchte ich behaupten, dass das durch irgendeine Emulationsschicht läuft und da könnte es durchaus sein, dass die 32bit Executable einen hohen Overhead verursacht.

Zitat:

Zitat von mytbo (Beitrag 1523584)
PlattformLaufzeit: Inc(sum)Laufzeit: sum := sum + 1
32 Bit1.82s (1822103 us)1.69s (1693918 us)
64 Bit294.65ms (294654 us)294.85ms (294857 us)

Verwende ich sum in der Ausgabe (ShowMessage) nicht, sehen die Ergebnisse für 32-Bit so aus:
PlattformLaufzeit: Inc(sum)Laufzeit: sum := sum + 1
32 Bit294.92ms (294925 us)1.68s (1688951 us)
Die Werte für 64-Bit ändern sich nicht.

Alle Messwerte in mehreren Durchläufen verifiziert.

Inc für Int64 ist scheinbar leider etwas unglücklich implementiert unter 32bit und sorgt nicht für denselben Code.

Mit + bekomm ich diese Ergebnisse:

Win32: ca 290ms
Win64: ca 220ms

Außerdem ist es immer gefährlich den Zeitmessungscode und die Ausgabe, welche fast immer strings beinhaltet mit in dieselbe Routine zu packen, wie den Code, den man messen möchte. Das kann u.U. katastrophale (im Sinne der gemessenen Zeit) haben, da der Compiler für strings und andere gemanagte Typen ein implizites try/finally erzeugt und dieses besonders unter 32bit dafür sorgt, dass der Compiler jegliche werte immer über den Stack bezieht anstatt sie in Registern zu behalten.

Zurück zum Inc auf 32bit:

Erzeugt diesen code:

Code:
add dword ptr [ebp-$18],$01
adc dword ptr [ebp-$14],$00
Delphi-Quellcode:
sum := sum + 1;
erzeugt diesen:

Code:
mov eax,[ebp-$18]
mov edx,[ebp-$14]
add eax,$01
adc edx,$00
mov [ebp-$18],eax
mov [ebp-$14],edx
"Aber Stevie, das ist doch mehr Code, warum läuft der langsamer?"
Dafür müssen wir uns mal anschauen, wie die Timings dieser Befehle sind und dazu kann man dieses Dokument zurate ziehen.

Genauer gesagt, schauen wir uns add und adc mit den Operanden m,r/i an (das, was Inc erzeugt) - ich nehme dafür die Timings von Icelake auf Seite 349. Wenn wir in die Spalte Latency gehen, sehen wir dort eine für die Performance vernichtende 7. Der Code, welcher für die Addition genutzt wird nutzt add und adc mit den Operanden r,r/i, die eine Latenz von 1 haben. Die zusätzlichen mov Befehle werden hier vermutlich durch die sogenannte "mov elimination" von der CPU entfernt, da sie erkennt, dass man immer nur denselben Wert schreibt und liest (das ist aber unbestätigt und nur eine Vermutung meinerseits, dafür müsste ich den Code genauer profilen).

MEissing 20. Jun 2023 15:22

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Ja. Sicherlich.

Aber darum geht/ging es doch (siehe Betreff)

Stevie 20. Jun 2023 16:25

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von MEissing (Beitrag 1523587)
Ja. Sicherlich.

Aber darum geht/ging es doch (siehe Betreff)

Ich lese aus dem Betreff "Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64" nicht, dass es um den Vergleich zwischen nativ für ARM kompiliert und Win32 und Win64 kompilate in ner Windows VM laufen lassen geht :glaskugel:

Rollo62 20. Jun 2023 18:14

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Wäre es denkbar dass solche krassen Unterschiede x10 auch durch Intel vs.AMD kommen könnten?
Hier wird wohl Intel favorisiert, aber ich vermute AMD liegt da gleichauf.
Oder ist das eine falsche Annahme ?

Blup 20. Jun 2023 18:53

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von mytbo (Beitrag 1523584)
Verwende ich sum in der Ausgabe (ShowMessage) nicht, sehen die Ergebnisse für 32-Bit so aus:

Da sollte man sich wirklich den erzeugten Code genauer anschauen.
Sicher das der Compiler das
Delphi-Quellcode:
Inc(Sum)
nicht einfach wegoptimiert?
Ein schlauer Compiler könnte sogar die Schleife wegoptimieren
Delphi-Quellcode:
Inc(Sum, RUN_COUNT)
.

Wichtig ist sicher, ob der erzeugte Code für die Schleife vollständig in die Befehlswarteschlange des Prozessorkerns passt und die Sprungvorhersage richtig liegt.

Stevie 20. Jun 2023 20:02

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Rollo62 (Beitrag 1523593)
Wäre es denkbar dass solche krassen Unterschiede x10 auch durch Intel vs.AMD kommen könnten?
Hier wird wohl Intel favorisiert, aber ich vermute AMD liegt da gleichauf.
Oder ist das eine falsche Annahme ?

Es gibt sicherlich vereinzelt Unterschiede bei den Timings zwischen den Herstellern und auch zwischen den verschiedenen Generationen aber speziell bei dem hier besprochenen Code sehe ich diesen nicht.
Solang nicht detailiertere Information vorliegen vermute ich entweder die Virtualisierungs-/Emulationssschicht oder das Benutzen von Inc anstatt +1 als Ursache.
In dem zuvor verlinkten Dokument stehen auch die Instructiontimings von AMD einschließlich Zen 4.

Zitat:

Zitat von Blup (Beitrag 1523594)
Wichtig ist sicher, ob der erzeugte Code für die Schleife vollständig in die Befehlswarteschlange des Prozessorkerns passt und die Sprungvorhersage richtig liegt.

Die Schleife ist so klein, die passt in eine cacheline. Und die Sprungvorhersage ist ziemlich sicher 999999999 mal richtig und nur das letzte mal falsch.

Der schöne Günther 20. Jun 2023 20:59

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Stevie (Beitrag 1523596)
das Benutzen von Inc anstatt +1 als Ursache

Kann mich jemand aufklären, wo hier der Unterschied liegen soll?

jaenicke 20. Jun 2023 21:30

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1523597)
Kann mich jemand aufklären, wo hier der Unterschied liegen soll?

In den aktuellen Implementierungen generiert der Compiler in beiden Fällen den gleichen Code.

Stevie 20. Jun 2023 22:57

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1523597)
Zitat:

Zitat von Stevie (Beitrag 1523596)
das Benutzen von Inc anstatt +1 als Ursache

Kann mich jemand aufklären, wo hier der Unterschied liegen soll?

Siehe Post #15

MEissing 21. Jun 2023 07:07

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von Stevie (Beitrag 1523589)
Zitat:

Zitat von MEissing (Beitrag 1523587)
Ja. Sicherlich.

Aber darum geht/ging es doch (siehe Betreff)

Ich lese aus dem Betreff "Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64" nicht, dass es um den Vergleich zwischen nativ für ARM kompiliert und Win32 und Win64 kompilate in ner Windows VM laufen lassen geht :glaskugel:

In der Tat ist in einer Windows 11/ARM-VM-Umgebung das Ergebnis ein komplett anderes, als auf direkter, "nativer" Umgebung.

Windows 11/ARM in Parallels VM auf M1 Max (original Code, Post#1)
Win32/Release
Int64: 5987 ms
Integer: 712 ms
-> Faktor 8

Windows 11 auf Intel NUC Intel i7-1360p (original Code, Post#1)
Win32/Release
Int64: 270 ms
Integer: 205 ms
-> Faktor 1,3

Also Int64 in einer Windows11-VM auf ARM -> "Langsam"

QuickAndDirty 21. Jun 2023 08:49

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Zitat:

Zitat von MEissing (Beitrag 1523602)
Also Int64 in einer Windows11-VM auf ARM -> "Langsam"

Das sowas überhaupt geht. Wenn man drüber nachdenkt. Wir leben echt in der Zukunft.

himitsu 21. Jun 2023 14:07

AW: Geschwindigkeitsunterschiede Apple Sillicon / Intel Win32 / Win64
 
Apple hat für seinen ARM etwas eingebaut (Name vergessen),
was eine x86 CPU (vermutlich x64) emuliert.

Könnte man entfernt mit Wine (Windows-Anwendung im Linux),
bzw. eher mit 16 und 32 Bit in einer mit 64 Bit-CPU, sowie 16 Bit in einer mit 32 Bit-CPU.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz